You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Widget:RemoteViewsFactory的onDataSetChanged协程与请求安全问题

关于Android App Widget RemoteViewsFactory onDataSetChanged()的协程实现疑问

背景

我需要在Android App Widget中展示最新电影图片,要求Widget每小时刷新以获取最新数据。应用全程使用协程,需调用现有Retrofit服务的挂起函数获取数据。根据Android文档,RemoteViewsFactory的onDataSetChanged方法内可安全执行耗时操作,因此选择在此方法中从服务获取数据而非WorkManager(WorkManager在App Widget场景存在缺陷)。

Android文档说明:

当远程适配器触发notifyDataSetChanged()时调用。允许RemoteViewsFactory通过更新内部引用来响应数据变化。注意:耗时任务可在此方法内同步安全执行,期间Widget将显示旧数据。

我当前使用runBlocking()实现阻塞式Retrofit调用,避免getView在数据获取完成前触发。适配器每小时会在MyWidgetProvider的onUpdate方法中被通知更新。

代码片段

MyWidgetProvider的onUpdate方法

override fun onUpdate(
    context: Context,
    appWidgetManager: AppWidgetManager,
    appWidgetIds: IntArray
) {
   ....
   appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.listViewMovies)
   .....
 }

MyRemoteViewsFactory实现

class MyRemoteViewsFactory : RemoteViewsFactory {
    private var job: Job? = null
    private var data: List<Movie>? = null
    private val service: MovieService = ... // 初始化Retrofit服务

    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()
    }

    // 其他必要的RemoteViewsFactory方法(如getCount、getViewAt等)实现...
}

日志信息

控制台日志显示onDestroy()在不同Binder线程被调用:

onCreate _main
1 _Binder:11940_5
2 _Binder:11940_5
...
onDestroy _Binder:11940_2
Clear called _Binder:11940_2

疑问

  • 在onDataSetChanged方法内使用runBlocking是否安全?
  • 在runBlocking内创建嵌套协程以取消协程是否安全?有无更优方案?
  • 在onDataSetChanged内进行网络请求是否安全?
  • 无法在onDataSetChanged内进行异步调用,有无无需使用runBlocking的处理方式?

内容的提问来源于stack exchange,提问作者Jess

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:24:19