谁能帮我找出我哪里出错了。每当 Worker 发生数据更改时,我需要不断观察网络数据并更新 UI。请注意,这在升级到 androidx 之前是有效的。
这是一个 Worker 类。
class TestWorker(val context: Context, val params: WorkerParameters): Worker(context, params){
override fun doWork(): Result {
Log.d(TAG, "doWork called")
val networkDataSource = Injector.provideNetworkDataSource(context)
networkDataSource.fetchData(false)
return Worker.Result.SUCCESS
}
companion object {
private const val TAG = "MY_WORKER"
}
}
如下调用:
fun scheduleRecurringFetchDataSync() {
Log.d("FETCH_SCHEDULER", "Scheduling started")
val fetchWork = PeriodicWorkRequest.Builder(TestWorker::class.java, 1, TimeUnit.MINUTES)
.setConstraints(constraints())
.build()
WorkManager.getInstance().enqueue(fetchWork)
}
private fun constraints(): Constraints{
return Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.build()
}
我还有一个 UserDao 和 UserRepository 来获取和存储数据。我正在观察 UserRepository 中的网络数据如下:
class UserRepository (
private val userDao: UserDao,
private val networkDataSource: NetworkDataSource,
private val appExecutors: AppExecutors){
init {
val networkData= networkDataSource.downloadedData
networkData.observeForever { newData->
appExecutors.diskIO().execute {
userDao.insert(newData.user)
}
}}
谁能帮我找出哪里出错了。这给了我如下错误:
java.lang.IllegalStateException: Cannot invoke observeForever on a background thread
at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:443)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:204)
at com.example.app.data.repo.UserRepository.<init>(UserRepository.kt:17)
at com.example.app.data.repo.UserRepository$Companion.getInstance(UserRepository.kt:79)
最佳答案
改变这个:
networkData.observeForever { newData->
appExecutors.diskIO().execute {
userDao.insert(newData.user)
}
}
收件人:
变体 B(带有协程):
GlobalScope.launch(Dispatchers.Main) { networkData.observerForever { /*..*/ } }
但请注意,GlobalScope
的用法不推荐:https://stackoverflow.com/a/54351785/1185087
变体 A(无协程):
Handler(Looper.getMainLooper()).post { networkData.observeForever{ /*..*/ } }
说明
通常 observe(..)
和 observeForever(..)
应该从主线程调用,因为它们的回调 (Observer<T>.onChanged(T t)
) 经常改变 UI,这只能在主线程中进行。这就是为什么android会检查observe函数的调用是否由主线程完成的原因。
在你的情况下 UserRepository.init{}
由后台线程调用,因此抛出异常。要切换回主线程,您可以使用上述变体之一。但请注意,观察回调中的代码也由主线程执行。此回调中的任何昂贵处理都会卡住您的 UI!
关于android - java.lang.IllegalStateException : Cannot invoke observeForever on a background thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52623018/