ConcurrentModificationException Room Android [英] ConcurrentModificationException Room Android

查看:35
本文介绍了ConcurrentModificationException Room Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用 Room,在将数据插入我的数据库时,有时会抛出 ConcurrentModificationException.为什么会这样?

I am using Room in my app and while inserting data into my db a ConcurrentModificationException is thrown at times. Why is it so?

我使用分页 api,在每次 api 调用后,我使用

I use a pagination api and after each api call I insert dataList into my db using

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

推荐答案

如果您尝试在分页列表中插入数据,这是一个典型的场景.由于您尚未粘贴错误日志,因此我假设该错误是由 dataList 对象引起的.在这种情况下,错误消息将如下所示.

This is a typical scenario if you are trying to insert data in a paginated list. Since you have not pasted error logs, i assume that the error is caused on the dataList object. In that case the error message woule look like below.

 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 复制到一个新变量,并将新的局部变量用作插入调用的参数.

If this is the case, the error is caused by paralell modification of same variable by different threads. In this case i assume that you are inserting the data to database and at the same doing new service call(pagination) to fetch data updating the same data object. Or this can be thrown even if you remove the contents from original array source while it is being inserted. The solution is pretty simple. You can copy the variable dataList to a new variable and use the new local variable as parameter to your insert call.

例如:(科特林)

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

这篇关于ConcurrentModificationException Room Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆