我在我的应用程序中使用Room,并且在将数据插入我的数据库时,有时会抛出ConcurrentModificationException
。为什么会这样?
我使用分页api,在每次api调用后,我使用
将dataList插入到我的数据库中new Thread(new Runnable() {
@Override
public void run() {
appDatabase.dataDao().insertMultipleData(dataList);
}
}).start();
,其中
appDatabase = Room.databaseBuilder(context, AppDatabase.class, AppDatabase.DATABASE_NAME)
.fallbackToDestructiveMigration()
.build();
插入操作
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertMultipleData(List<Data> dataList);
答案 0 :(得分:0)
如果您尝试在分页列表中插入数据,这是一种典型情况。由于您尚未粘贴错误日志,因此我认为错误是在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 复制到新变量,并使用新的本地变量作为插入调用的参数。
例如:(科特琳)
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