房间获取 ConcurrentModificationException

Room getting ConcurrentModificationException

我在向 Android table 插入数据时遇到问题。这是我的 Dao 函数:

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(freight: Foo)

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(freights: MutableList<Foo>)

调用方法如下:

  Observable.fromCallable {
          db.fooDao().insert(it)
       }
    }
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .subscribe {
                Logger.d("Inserted ${it} users from API in DB...")
            }

我得到异常:

   Caused by: java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.next(ArrayList.java:860)
    at com.blockgrain.blockgrain.dbmanager.repository.FooRepository$insertDataInDb.call(FooRepository.kt:76)

我用相同的逻辑创建了其他 tables,它们工作正常,但这个失败了。请让我知道哪里出了问题。

更新 :

Foo.kt

 override fun get(): Observable<MutableList<Foo>> {
    val observable = getDataFromDb()
    return observable.flatMap {
        if (it.isEmpty())
            getDataFromApi()
        else
            observable
    }
}

override fun getDataFromApi(): Observable<MutableList<Foo>> {

    return WebService.createWithAuth().getFooFromWeb()
            .doOnNext {
                Logger.d(" Dispatching ${it} users from API...")
                Observable.fromCallable {
                     db.fooDao().insert(it)
                      }
                  }
                  .subscribeOn(Schedulers.io())
                  .observeOn(Schedulers.io())
                  .subscribe {
                           Logger.d("Inserted ${it} users from API in DB...")
                  }
               }
}

根据给定的代码,不直接清楚如何调用数组列表修改导致 Caused by: java.util.ConcurrentModificationException。 我的猜测是,一次在同一个列表上执行多个操作。

您在 dao 中的插入列表方法正在接受 MutableList<Foo> 将其更改为 List<Foo>,因为 Room 不需要可变列表。像这样,

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(freights: List<Foo>)

我建议在像这样对列表进行任何操作之前将数组列表复制到另一个列表

// Before performing any operation on list
var newList:List<Foo> = ArrayList<Foo>(otherList)
// Perform operation on newList - for ex.
db.insert(newList)

如果您想与 CopyOnWriteArrayList 同时使用 ArrayList,还有另一种解决方案。但这将导致对现有代码进行重大修改。所以我建议选择第一个选项。