ConcurrentModificationException Room Android

5

我在我的应用程序中使用Room,当向数据库插入数据时,有时会抛出ConcurrentModificationException异常。为什么会这样呢?

我使用分页API,在每次API调用后,使用以下代码将dataList插入到我的数据库中:

new Thread(new Runnable() {
            @Override
            public void run() {                    
                    appDatabase.dataDao().insertMultipleData(dataList);                    
            }
        }).start();

where

appDatabase = Room.databaseBuilder(context, AppDatabase.class, AppDatabase.DATABASE_NAME)
                .fallbackToDestructiveMigration()
                .build();

插入操作

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertMultipleData(List<Data> dataList);
1个回答

2

如果你正在尝试在分页列表中插入数据,那么这是一个典型的情况。由于你没有粘贴错误日志,我假设错误是在dataList对象上引起的。在这种情况下,错误消息应该如下所示。

 java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.next(ArrayList.java:860)
        at androidx.room.EntityInsertionAdapter.insertAndReturnIdsArray(EntityInsertionAdapter.java:131)
        at com.myApp.data.database.entities.FeedDataDao_Impl.insertAll(FeedDataDao_Impl.java:220)

如果是这种情况,错误是由不同线程对同一变量进行并行修改引起的。在这种情况下,我假设您正在将数据插入数据库,并同时进行新的服务调用(分页)以获取更新相同数据对象的数据。或者,即使在插入时从原始数组源中删除内容,也可能会抛出此错误。解决方案非常简单。您可以将变量 dataList 复制到一个新变量中,并使用新的局部变量作为您的插入调用参数。
例如:(Kotlin)
val localCopy = dataList
CoroutineScope(Dispatchers.IO).launch {

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

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

例如:(Java)

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

我的问题和这个一样,但是这个解决方案对我不起作用。请查看 https://stackoverflow.com/questions/68082863/java-util-concurrentmodificationexception-at-java-util-arraylistitr-next - Ritu
1
讲解得很清楚,谢谢!在我的情况下,我同时删除数据和加载数据! - Mostafa Onaizan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接