Insert over 6000 records in sqlite - android?

泄露秘密 提交于 2019-12-25 09:15:24

问题


I get a lot of records from webService (over 5000) and then I need to Insert them in my sqlite but when I Insert them in my sqlite get a long time for Insert and often get me crash. What can I do?

My insert item is same below:

public long InsertData(Marketing_Points_B MP, Context context) {
    DBS db = new DBS(context);
    PACKAGE_NAME = context.getApplicationContext().getPackageName();
    db.GetPackageName(PACKAGE_NAME);
    db.CreateFile();
    try {
        db.CreateandOpenDataBase();
    } catch (IOException e) {
        e.printStackTrace();
    }
    sql = db.openDataBase();
    ContentValues values = new ContentValues();
    values.put("Count", MP.getCounts());
    values.put("mDate", MP.getDate());
    values.put("mTime", MP.getTime());
    values.put("xLat", String.valueOf(MP.getLat()));
    values.put("yLng", String.valueOf(MP.getLng()));
    values.put("UserId", MP.getUserCode());

    long LastId = sql.insert("ReportAct_tbl", null, values);
    sql.close();
    return LastId;
}

My LogCat:

08-10 13:05:47.470 988-2132/? E/qdlights: [BL] mode=0 brightness=10
08-10 13:05:50.090 988-4931/? E/qdlights: [BL] mode=0 brightness=255
08-10 13:06:02.720 21447-21447/? E/cutils-trace: Error opening trace file: No such file or directory (2)
08-10 13:06:21.090 988-1000/? E/Sensors: poll() failed (Interrupted system call)
08-10 13:06:22.320 988-1004/? E/ActivityManager: ANR in com.ir.zanis.marketing_manager (com.ir.zanis.marketing_manager/.ReportActivity_B)
                                                 Reason: keyDispatchingTimedOut
                                                 Load: 8.13 / 7.87 / 7.75
                                                 CPU usage from 15696ms to 0ms ago:
                                                   33% 19742/com.ir.zanis.marketing_manager: 20% user + 13% kernel / faults: 425 minor
                                                   26% 436/sdcard: 0.5% user + 26% kernel
                                                   3.8% 169/mmcqd/0: 0% user + 3.8% kernel
                                                   2.2% 24138/com.ucloudy.jewel: 1.5% user + 0.7% kernel / faults: 6627 minor 5 major
                                                   1.9% 988/system_server: 1.2% user + 0.7% kernel / faults: 407 minor 4 major
                                                   1.2% 438/adbd: 0.3% user + 0.9% kernel / faults: 1377 minor
                                                   0.4% 346/netd: 0.4% user + 0% kernel / faults: 11 minor
                                                   0.3% 20276/ksoftirqd/1: 0% user + 0.3% kernel
                                                   0.2% 3/ksoftirqd/0: 0% user + 0.2% kernel
                                                   0.2% 1867/mpdecision: 0% user + 0.2% kernel
                                                   0.1% 24070/kworker/0:2H: 0% user + 0.1% kernel
                                                   0.1% 1194/com.android.systemui: 0% user + 0% kernel
                                                   0% 1318/com.google.android.gms.persistent: 0% user + 0% kernel / faults: 836 minor 11 major
                                                   0% 1457/com.google.android.gms: 0% user + 0% kernel / faults: 649 minor 63 major
                                                   0.1% 24459/com.dewmobile.kuaiya.play: 0.1% user + 0% kernel / faults: 103 minor 2 major
                                                   0% 1//init: 0% user + 0% kernel / faults: 208 minor
                                                   0% 349/surfaceflinger: 0% user + 0% kernel
                                                   0% 1096/RX_Thread: 0% user + 0% kernel
                                                   0% 1136/wpa_supplicant: 0% user + 0% kernel / faults: 1 major
                                                   0% 1559/com.yirga.shutapp.Accessibility: 0% user + 0% kernel / faults: 37 minor
                                                   0% 13217/kworker/u:1: 0% user + 0% kernel
                                                   0% 13271/kworker/0:1: 0% user + 0% kernel
                                                   0% 19633/kworker/u:2: 0% user + 0% kernel
                                                   0% 20281/kworker/1:1: 0% user + 0% kernel
                                                  +0% 21667/kworker/1:2H: 0% user + 0% kernel
                                                 65% TOTAL: 13% user + 25% kernel + 26% iowait + 0.3% softirq
                                                 CPU usage from 1080ms to 1601ms later:
                                                   32% 19742/com.ir.zanis.marketing_manager: 25% user + 7.6% kernel / faults: 8 minor
                                                     30% 19742/rketing_manager: 23% user + 7.6% kernel
                                                   26% 436/sdcard: 0% user + 26% kernel
                                                     15% 436/sdcard: 0% user + 15% kernel
                                                     13% 470/sdcard: 0% user + 13% kernel
                                                   3.8% 169/mmcqd/0: 0% user + 3.8% kernel
                                                   3.8% 988/system_server: 0% user + 3.8% kernel / faults: 1 minor
                                                     3.8% 1004/ActivityManager: 0% user + 3.8% kernel
                                                   1.9% 438/adbd: 1.9% user + 0% kernel / faults: 48 minor
                                                 57% TOTAL: 10% user + 19% kernel + 28% iowait
08-10 13:06:28.840 349-566/? E/libEGL: eglMakeCurrent:671 error 3009 (EGL_BAD_MATCH)
08-10 13:06:28.910 21912-21918/? E/jdwp: Failed sending reply to debugger: Broken pipe
08-10 13:06:29.230 21912-21912/? E/RecyclerView: No adapter attached; skipping layout
08-10 13:06:29.300 21912-21912/? E/RecyclerView: No adapter attached; skipping layout

回答1:


To insert more record in database,You should use transaction with prepared statement that reduced the insertion time. For example:

 public void insertFast(int insertCount) {

        // you can use INSERT only
        String sql = "INSERT OR REPLACE INTO " + tableName + " ( name, description ) VALUES ( ?, ? )";

        SQLiteDatabase db = this.getWritableDatabase();

        /*
         * According to the docs http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
         * Writers should use beginTransactionNonExclusive() or beginTransactionWithListenerNonExclusive(SQLiteTransactionListener) 
         * to start a transaction. Non-exclusive mode allows database file to be in readable by other threads executing queries.
         */
        db.beginTransactionNonExclusive();
        // db.beginTransaction();

        SQLiteStatement stmt = db.compileStatement(sql);

        for(int x=1; x<=insertCount; x++){

            stmt.bindString(1, "Name # " + x);
            stmt.bindString(2, "Description # " + x);

            stmt.execute();
            stmt.clearBindings();

        }

        db.setTransactionSuccessful();
        db.endTransaction();

        db.close();
    }

For details, how to use transaction see this tutorial

Use can also see, how to perform all db operation in transaction:

http://www.codota.com/android/methods/android.database.sqlite.SQLiteDatabase/beginTransaction




回答2:


I don't think you should do that many sql writes on the client (especially if this number of 6000 is likely to grow). Why don't you prepare the (compressed) sql db file on the server and send that over to your android client? This will certainly be faster and more battery friendly.




回答3:


I suggest you to insert these records through an another webservice ,firstly. Then update your android local Sqlite db file.

You can also have a look at following codes :

<?php

/*
 * PHP SQLite - Create a table and insert rows in SQLite
 */

//Open the database mydb
$db = new SQLite3('db/mydb');

//drop the table if already exists
$db->exec('DROP TABLE IF EXISTS people');

//Create a basic table
$db->exec('CREATE TABLE people (full_name varchar(255), job_title varchar (255))');
echo "Table people has been created \n";

//insert rows
$db->exec('INSERT INTO people (full_name, job_title) VALUES ("John Doe","manager")');
echo "Row inserted \n";
$db->exec('INSERT INTO people (full_name, job_title) VALUES ("Jane Cyrus","assistant")');
echo "Row inserted \n";

?>



回答4:


If you're getting ANR then it is very likely that your code that writes to the database is running in the UI thread. Please keep that part separate and running in another thread.

Use for instance AsyncTask: more info at https://developer.android.com/reference/android/os/AsyncTask.html



来源:https://stackoverflow.com/questions/38867973/insert-over-6000-records-in-sqlite-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!