我用我的布局中包含的所有视图创建了一个纵向布局的横向变化。
但是当我运行应用程序并旋转设备时,有一个崩溃的错误:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: com.user.project_name, PID: 15543
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at com.user.project_name.MainActivity$findSingleCountry$1.invokeSuspend(MainActivity.kt:157)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
这个错误指的是我的MainActivity上的这个代码:
private fun findSingleCountry(name: String) {
CoroutineScope(Dispatchers.Default).launch {
fiscalCode.birthPlace = "X999"
for (country in countryList) {
if (country.description.uppercase() == name.uppercase()) {
fiscalCode.birthPlace = country.code
break
}
}
cFViewModel.getFiscalCode(fiscalCode)
}
}
第157行是:for (country in countryList) {
我只在onCreate()中调用这个方法:
binding.acBirthCountry.setOnItemClickListener { adapterView, _, itemPos, _ ->
fiscalCode.birthPlace = (adapterView.adapter.getItem(itemPos) as CountryModel).code
cFViewModel.getFiscalCode(fiscalCode)
}
binding.acBirthCountry.doAfterTextChanged { name ->
findSingleCountry(name.toString())
}
为什么我的应用程序只有在进入横向模式时才会崩溃?
编辑:
如何在主线程中不运行函数的情况下解决这个问题?
编辑:
根据文档:
注意,这个异常并不总是表明一个对象被另一个线程并发地修改了。如果单个线程发出的一系列方法调用违反了对象的契约,则该对象可能会抛出此异常。例如,如果线程在使用快速失败迭代器迭代该集合时直接修改了该集合,则迭代器将抛出此异常。
这个异常只是警告代码可能违反了对象的契约,实际上,当设备切换到横向模式时,方法findSingleCountry
不会被调用。
当我进入横向模式时忽略异常是这种情况吗?
问题很可能在于集合countryList
被Main
线程修改(可能只是重新创建),而另一个线程(在您的情况下是Default
)迭代该集合。您可以查看ConcurrentModificationException
:
此异常可能由检测到对象的并发修改(当这种修改是不允许的)的方法抛出。
例如,通常不允许一个线程在另一个线程迭代Collection时修改Collection。通常,在这些情况下,迭代的结果是未定义的。
知道Main
线程是onCreate
方法操作的线程,我认为改变线程调度程序会有所帮助。试着这样修改你的代码:
CoroutineScope(Dispatchers.Main).launch {
...
}
编辑:
函数findSingleCountry
可能只在onCreate
方法中执行,所以我认为将代码从CoroutineScope
中取出实际上会更有帮助.