如何在另一个线程中将数据插入数据库

时间:2016-12-13 09:41:06

标签: android multithreading sqlite android-asynctask

我从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线程。如何将数据库插入移动到另一个线程?

1 个答案:

答案 0 :(得分:1)

据我所知,您正在尝试批量插入,我会为您的案例推荐以下方法:

1)在循环

之前创建内容操作的arraylist
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

2)在for循环中创建contentoperation并将其添加到arraylist,如下所示

 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);

是的,您需要使用内容提供程序,我建议这样做,而不是为db操作编写SQL查询。