【问题标题】:how to insert data to database in another thread如何在另一个线程中将数据插入数据库
【发布时间】:2017-04-28 07:39:38
【问题描述】:

我在 AsyncTask 中从服务器下载数据,然后将其写入数据库。下面是 doInBackground 方法的一部分:

DBConnection db = new DBConnection(context);    
JSONObject json = new JSONObject(s);
                JSONObject cataloglist = json.getJSONObject("cataloglist");

                JSONArray array = cataloglist.names();
                db.clearNomenclature();
                for(int n = 0; n < array.length(); n++)
                {
                    JSONObject object = cataloglist.getJSONObject(array.getString(n));
                    db.insertNomenclature(object.getInt("version"), object.getString("name"), object.getString("uuid"), object.getString("measure"));
                }

这里我访问了 DBConnection 类,在 DBConnection 类的 insertNomenclature 方法中,我将数据插入到数据库中,如下所示:

        dbOpenHelper = new ExternalDbOpenHelper(context, "DB");
        database = dbOpenHelper.getWritableDatabase();
        database.execSQL("CREATE TABLE IF NOT EXISTS "+"nomenclature"+
                " ("+"ID"+" INTEGER PRIMARY KEY AUTOINCREMENT, "+
                "name TEXT, version INTEGER, measure UUID, uuid UUID)");

                ContentValues cv = new ContentValues();
                cv.put("name", name);
                cv.put("version", version);
                cv.put("uuid", uuid);
                cv.put("measure", measure);
                database.insert("nomenclature", null, cv);
                database.close();

在日志中我经常收到这样的消息:

12-12 12:11:40.825 26770-26770/com.example.sanzharaubakir.exgroup I/Choreographer: Skipped 4205 frames!  The application may be doing too much work on its main thread.

我希望在后台执行数据库插入,但显然它以某种方式在 UI 线程上工作。如何将数据库插入移动到另一个线程?

【问题讨论】:

  • doInBackground 运行在一个单独的线程上,你确定是运行造成的跳帧吗?
  • 当我删除这一行时 db.insertNomenclature(object.getInt("version"), object.getString("name"), object.getString("uuid"), object.getString("measure) "));我没有收到这样的消息

标签: android multithreading sqlite android-asynctask


【解决方案1】:

我的理解是您正在尝试进行批量插入,我会针对您的情况推荐以下方法:

1) 在循环之前创建一个内容操作的arraylist

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

2) 在 for 循环中创建内容操作并将其添加到数组列表中,如下所示

 ContentValues values = new ContentValues();
 values.put(COLUMN_NAME, VALUE);
 ContentProviderOperation operation = ContentProviderOperation.newInsert(ZoneConfigContract.ZoneInfo.CONTENT_URI).withValues(values).withYieldAllowed(true).build();
 ops.add(operation);

3) 然后,最后只应用批处理

getContentResolver().applyBatch(AUTHORITY, ops);

是的,您需要为此使用内容提供程序,我建议您不要为数据库操作编写 sql 查询。

【讨论】:

    猜你喜欢
    • 2018-02-09
    • 2018-03-13
    • 2023-04-10
    • 2015-03-31
    • 2014-11-21
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多