在后台任务(Android)中更新数据库

时间:2016-05-19 16:30:33

标签: android sqlite android-asynctask sqliteopenhelper

我的应用程序使用SQLiteDatabase将两个arraylists保存到单独的表中。

我注意到,自从实现数据库以来,无论何时更新数据库(包括删除表,重新创建它们,然后用arraylists填充它们),应用程序都会暂时冻结,我在logcat中收到以下消息: " I / Choreographer:跳过236帧!应用程序可能在其主线程上做了太多工作。"

为了确认这是更新,我删除了用于更新数据库的代码。这样做后,我不再收到警告信息,我的应用程序也没有冻结。

这是我的自定义数据库帮助程序中的代码,它扩展了SQLiteOpenHelper,用于更新表:

 public void insertData(ArrayList<SavedWifiHotspot> hotspots, ArrayList<MarkerOptions> markers) {
    Log.d("insert LocationsDB", "Data inserted");
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues hotspotValues = new ContentValues();
    ContentValues markerValues = new ContentValues();
    for(SavedWifiHotspot hotspot : hotspots) {
        hotspotValues.put("Ssid", hotspot.getSsid());
        hotspotValues.put("Password", hotspot.getPassword());
        hotspotValues.put("LocationName", hotspot.getHotspotLoc());
        hotspotValues.put("Lat", hotspot.getLatitude());
        hotspotValues.put("Lng", hotspot.getLongitude());
        db.insert(HOTSPOT_TABLE_NAME, null, hotspotValues);
    }
    for(MarkerOptions marker : markers) {
        markerValues.put("LocationName", marker.getTitle());
        markerValues.put("Lat", marker.getPosition().latitude);
        markerValues.put("Lng", marker.getPosition().longitude);
        db.insert(LOCATION_TABLE_NAME, null, markerValues);
    }
}

这是用于在更新表之前清除表格的代码:

public void clearData() {
    Log.d("clear LocationsDB", "Tables cleared");
    SQLiteDatabase db=this.getWritableDatabase();

    String dropHSTable = "DROP TABLE IF EXISTS "
            + HOTSPOT_TABLE_NAME + ";";

    String dropLocTable = "DROP TABLE IF EXISTS "
            + LOCATION_TABLE_NAME + ";";

    db.execSQL(dropHSTable);
    db.execSQL(dropLocTable);

    createTables(db);
}

我应该如何在后台更新我的数据库?我读过有关线程的文章,我应该用线程来做这个吗?

编辑:这是错误,参考我的评论。

FATAL EXCEPTION: AsyncTask #5
Process: com1032.cw2.fm00232.fm00232_assignment2, PID: 8830
java.lang.RuntimeException: An error occured while executing doInBackground()
  at android.os.AsyncTask$3.done(AsyncTask.java:300)
  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
  at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
  at java.util.concurrent.ThreadPoolExe
  at java.lang.Thread.run(Thread.java:818)cutor$Worker.run(ThreadPoolExecutor.java:587)
Caused by: java.util.ConcurrentModificationException
  at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
  at com1032.cw2.fm00232.fm00232_assignment2.LocationsDB$3.doInBackground(LocationsDB.java:124)
  at at com1032.cw2.fm00232.fm00232_assignment2.LocationsDB$3.doInBackground(LocationsDB.java:119)
  at android.os.AsyncTask$2.call(AsyncTask.java:288)
  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
  at java.lang.Thread.run(Thread.java:818)

作为参考,第124行是:

for(MarkerOptions marker: markers[0]) {

第119行是:

new AsyncTask<ArrayList<MarkerOptions>, Void, Void>() {

Edit2:修正了上述问题。我的应用程序使用空列表调用插入数据方法。所以我在插入数据方法之前添加了.empty检查。

1 个答案:

答案 0 :(得分:2)

异步任务听起来不错。

{{1}}