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

在后台任务中更新数据库(Android),android,sqlite,android-asynctask,sqliteopenhelper,Android,Sqlite,Android Asynctask,Sqliteopenhelper,我的应用程序使用SQLiteDatabase将两个ArrayList保存到单独的表中 我注意到,自从实现数据库以来,每当它更新数据库(包括删除表、重新创建表,然后用ArrayList填充表)时,应用程序都会短暂冻结,我在logcat中收到以下消息: “I/Choreographer:跳过236帧!应用程序可能在其主线程上做了太多工作。” 为了确认是更新,我删除了用于更新数据库的代码。这样做之后,我不再收到警告信息,我的应用程序也没有冻结 这是自定义DB helper中的代码,它扩展了SQLite

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

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

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

这是自定义DB helper中的代码,它扩展了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);
    }
}
我应该如何在后台更新我的数据库?我已经读过关于线程的文章,我应该使用线程来做这件事吗

编辑:这是关于我的评论的错误

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>() {
newasynctask(){

Edit2:修复了上述问题。我的应用程序使用空列表调用插入数据方法。因此,我在插入数据方法之前添加了。空检查。

异步任务听起来是个好主意

public void insertData(ArrayList<SavedWifiHotspot> hotspots, ArrayList<MarkerOptions> markers) {
Log.d("insert LocationsDB", "Data inserted");

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

        @Override
        protected Void doInBackground(ArrayList<SavedWifiHotspot>... hotspots) {
            ContentValues hotspotValues = new ContentValues();
            for(SavedWifiHotspot hotspot : hotspots[0]) {
                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);
            }

        }
    }.execute(hotspots);

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

        @Override
        protected Void doInBackground(ArrayList<MarkerOptions>... options) {
            ContentValues hotspotValues = new ContentValues();
            for(MarkerOptions marker: options[0]) {
                markerValues.put("LocationName", marker.getTitle());
                markerValues.put("Lat", marker.getPosition().latitude);
                markerValues.put("Lng", marker.getPosition().longitude);
                db.insert(LOCATION_TABLE_NAME, null, markerValues);
            }

        }
    }.execute(options);
}


public void clearData() {
    Log.d("clear LocationsDB", "Tables cleared");
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            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);
        }
   }.execute();


}
public void insertData(ArrayList热点、ArrayList标记){
Log.d(“插入位置SDB”,“插入数据”);
新建异步任务(){
@凌驾
受保护的Void doInBackground(ArrayList…热点){
ContentValues热点值=新ContentValues();
对于(SavedWifiHotspot热点:热点[0]){
put(“Ssid”,hotspot.getSsid());
hospotvalues.put(“Password”,hospot.getPassword());
put(“LocationName”,hospot.gethospotloc());
hospotvalues.put(“Lat”,hospot.getLatitude());
hospotvalues.put(“Lng”,hospot.getLongitude());
插入(热点\表\名称,null,热点值);
}
}
}.执行(热点);
新建异步任务(){
@凌驾
受保护的Void doInBackground(ArrayList…选项){
ContentValues热点值=新ContentValues();
对于(标记选项标记:选项[0]){
markerValues.put(“LocationName”,marker.getTitle());
markerValues.put(“Lat”,marker.getPosition().lation);
markerValues.put(“Lng”,marker.getPosition().longitude);
db.insert(位置、表格、名称、null、MarkerValue);
}
}
}.执行(期权);
}
public void clearData(){
Log.d(“清除位置SDB”,“清除表格”);
新建异步任务(){
@凌驾
受保护的Void doInBackground(Void…参数){
SQLiteDatabase db=this.getWritableDatabase();
String dropHSTable=“如果存在,则删除表”
+热点_表_名称+“;”;
String dropOctable=“如果存在,则删除表格”
+位置表名称+“;”;
execSQL(dropHSTable);
db.execSQL(八进制);
创建表(db);
}
}.execute();
}

这是一款很容易学会如何使用的应用程序吗?基本上,我制作的这个应用程序是用于课程作业的,所以我的时间有点有限。这对你来说已经差不多了。如果它崩溃,请发布stacktrace,我可以帮你解决问题。看起来效果很好。我在关闭数据库时遇到问题。通常当活动暂停,但这现在似乎会导致insertData尝试访问关闭的数据库,即使在调用insertData之前在if语句中检查us db.isOpen。此外,doInBackground方法“为varargs参数创建未检查的泛型数组”上也会显示此警告。您是否在
onResume
方法中打开对数据库的引用?是的,在我的onResume中,我使用
if(!db.isOpen())
检查数据库是否打开,如果没有打开,则执行
db=locDB.getReadableDatabase()
。你能给我们看一下你的活动类代码吗?你是指活动类用来访问数据库的代码吗?
public void insertData(ArrayList<SavedWifiHotspot> hotspots, ArrayList<MarkerOptions> markers) {
Log.d("insert LocationsDB", "Data inserted");

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

        @Override
        protected Void doInBackground(ArrayList<SavedWifiHotspot>... hotspots) {
            ContentValues hotspotValues = new ContentValues();
            for(SavedWifiHotspot hotspot : hotspots[0]) {
                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);
            }

        }
    }.execute(hotspots);

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

        @Override
        protected Void doInBackground(ArrayList<MarkerOptions>... options) {
            ContentValues hotspotValues = new ContentValues();
            for(MarkerOptions marker: options[0]) {
                markerValues.put("LocationName", marker.getTitle());
                markerValues.put("Lat", marker.getPosition().latitude);
                markerValues.put("Lng", marker.getPosition().longitude);
                db.insert(LOCATION_TABLE_NAME, null, markerValues);
            }

        }
    }.execute(options);
}


public void clearData() {
    Log.d("clear LocationsDB", "Tables cleared");
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            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);
        }
   }.execute();


}