我从webService
(超过5000)获得了大量记录,然后我需要在Insert
中sqlite
这些记录,但当我Insert
在我的sqlite
时1}} Insert
花了很长时间,经常让我崩溃。我该怎么办?
我的插入项目如下:
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;
}
我的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
答案 0 :(得分:3)
要在数据库中插入更多记录,您应该使用具有减少插入时间的预准备语句的事务。例如:
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();
}
有关详细信息,请参阅交易see this tutorial
使用也可以看到,如何在事务中执行所有数据库操作:
http://www.codota.com/android/methods/android.database.sqlite.SQLiteDatabase/beginTransaction
答案 1 :(得分:0)
我认为你不应该在客户端上执行那么多sql写操作(特别是如果这个数量可能会增加6000)。为什么不在服务器上准备(压缩)sql db文件并将其发送到您的Android客户端?这肯定会更快,更适合电池使用。
答案 2 :(得分:0)
我建议您先通过另一个Web服务插入这些记录。然后更新你的android本地Sqlite db文件。
您还可以查看以下代码:
<?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";
?>
答案 3 :(得分:0)
如果您正在获取ANR,那么写入数据库的代码很可能正在UI线程中运行。请将该部分分开并在另一个线程中运行。
使用例如AsyncTask:更多信息https://developer.android.com/reference/android/os/AsyncTask.html