我正在尝试获取一些最新的电影图像,并将它们显示在Android应用程序的小部件中,按照要求,小部件应该每小时刷新一次,以获取最新的电影图像。
由于我在整个应用程序中都使用协同服务,所以我需要使用现有的带有挂起功能的更新服务来获取数据。
根据Android文档,在onDataSetChanged of RemoteViewsFactory中执行大量操作是安全的,因此我使用这个方法本身从服务中获取数据,而不是WorkManger,因为它有其自身的缺点。见这里(https://commonsware.com/blog/2018/11/24/workmanager-app-widgets-side-effects.html)
在远程适配器上触发notifyDataSetChanged()时调用。这允许RemoteViewsFactory通过更新任何内部引用来响应数据更改。注意:在此方法中可以安全地安全地执行昂贵的任务。在此期间,旧数据将显示在小部件中。
在下面的代码片段中,我使用runBlocking()来进行阻塞改造调用.否则,获取数据之前将触发get视图。这安全吗?
注意:在onUpdate方法的MyWidgetProvider中,每小时都会注意到适配器
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
....
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.listViewMovies)
.....
}代码示例: MyRemoteViewsFactory : RemoteViewsFactory {
override fun onDataSetChanged() {
try {
fetchFromServer()
} catch (e: Exception) {
clear()
}
}
private fun fetchFromServer() = runBlocking {
job = launch {
service.getMovieList?.also {
data = it
}
}
}
private fun clear(){
job?.cancel()
job = null
data = null
log("Cleared")
}
override fun onDestroy() {
clear()
}
Console log shows onDestory() s being called... but in different binder.
onCreate _main
1 _Binder:11940_5
2 _Binder:11940_5
3 _Binder:11940_5
4 _Binder:11940_5
5 _Binder:11940_5
6 _Binder:11940_5
7 _Binder:11940_5
8 _Binder:11940_5
9 _Binder:11940_5
10 _Binder:11940_5
11 _Binder:11940_5
onDestroy _Binder:11940_2
Clear called _Binder:11940_2所以我的问题是:
注意:这个问题特别适用于Android onDataSetChanged()实现.
发布于 2022-07-24 11:17:47
使用viewModel/lifeCycle作用域,runBlocking将阻塞UI线程。
发布于 2022-07-24 17:34:12
1-在runBlocking中使用onDataSetChanged方法安全吗? 3-从onDataSetChanged()内部的网络获取数据安全吗?
文档特别指出,“在此方法中可以安全地安全地执行昂贵的任务。在此期间,旧的数据将显示在小部件中。”
所以问题1和问题3的答案是肯定的,在那里使用runBlocking并进行网络呼叫是可以的。
2-在runBlocking内创建嵌套的协同线以取消协同线安全吗?还有更好的办法吗?
这样做可能没有真正的理由,因为runBlocking会阻塞线程,直到子协同完成为止,所以在工作完成之前,您不会将控制权还给调用者。见下一个问题。
4-我不能在onDataSetChanged()中进行异步调用。那么,我们是否可以不使用runBlocking()来处理
如果您想要启动以后可以取消的协同(在同时使用onDataSetChanged和clear (这还有待确认)的情况下),则应该声明一个CoroutineScope (作为类的属性),并使用该范围而不是使用runBlocking启动协同,然后在适当的时候/在适当的情况下取消该作用域。
https://stackoverflow.com/questions/73097689
复制相似问题