将数据插入Room Db时发生ConcurrentModificationException

时间:2019-10-09 18:54:21

标签: android

我基本上是尝试在房间db中保存一个截击响应,以便以后可以将其检索以供脱机使用,但是每次启动我的应用程序时,都会遇到此异常,我确实尝试了很多方法来解决该问题,但是没有为我工作,任何帮助将不胜感激的家伙。谢谢。

String api_keys = "MyApiKey" + awayid;

JsonObjectRequest jsonObjectRequest2 = new JsonObjectRequest(Request.Method.GET, api_keys, null, new Response.Listener<JSONObject>() {
               @Override
               public void onResponse(JSONObject response) {
                   try {
                       JSONArray jsonArray2 = response.getJSONArray("teams");

                       for (int i = 0; i < jsonArray2.length(); i++) {

                           JSONObject jsonObject2 = jsonArray2.getJSONObject(i);

                           String awaylogo = jsonObject2.getString("strTeamBadge");

                           modelList.add(new Model(eventid,myround, date, hometeam, awayteam, homelogo, awaylogo, homescore, 
      awayscore, stadium, "Details", mytime));

                           new Thread(new Runnable() {
                               @Override
                               public void run() {

                                   ApplicationDatabase database = DatabaseClient.getInstance(getApplicationContext()).getApplicationDatabase();

                               database.modelDao().insert(modelList); /// here it is the problem in this line

                              }
                          }).start();
                      } 
                  } catch (JSONException e) {
                      e.printStackTrace();
                  }
              }
          }, error -> {});

***这是我的道

@Dao
public interface  modelDAO {

    @Query("SELECT * FROM Model ")
    List<Model> listAll();

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(List<Model> model);

}

3 个答案:

答案 0 :(得分:0)

因为在for循环中启动了很多线程。 在for循环之后移动新线程。

答案 1 :(得分:0)

解决方案实际上是将模型对象传递给我的房间db而不是模型列表,因此希望此答案对其他人有所帮助。

答案 2 :(得分:0)

在将数据插入数据库时​​,是否在任何地方修改数据对象?在这种情况下,错误可能是由不同线程并行修改同一变量引起的。或即使在插入原始数组源中的内容时将其抛出,也可能引发该异常。房间插入操作是异步操作。如果使用协程运行插入,则可以在invokeOnCompletion块中获得完成。否则,如果确实需要修改对象而无需等待完成,则解决方案非常简单。您可以将变量 modelList 复制到新变量,并使用新的局部变量作为插入调用的参数。

例如:(科特琳)

val localCopy = modelList
CoroutineScope(Dispatchers.IO).launch {

        AppDatabase.getDatabase(context).feedDataDao().insertAll(localCopy).size

 }.invokeOnCompletion {
        Log.d("Inserted all items")
 }

例如:(Java)

List<MyDataType> localCopy = modelList       
AppDatabase.getDatabase(context).feedDataDao().insertAll(localCopy).size