我正在尝试创建一个小部件,如这个指南中所述,
...如果你的小部件设置过程可能需要几秒钟(也许是在执行网络请求),并且你需要继续进行处理,请考虑在onUpdate()方法中使用WorkManager启动Task。
但是,通过在onUpdate
方法中排队工作请求后,我会无限制地每隔大约半秒钟接收到相同意图传递的onUpdate
调用。我已经尝试使用goAsync()
和GlobalScope.launch
更新小部件以进行我的网络请求,这样可以正常工作。然而,建议使用workmanager api来完成i/o工作,这就是我要做的。
我通过New -> Widget -> App Widget菜单模板创建了一个应用程序小部件,并尝试这样排队工作:
class NewAppWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager,appWidgetIds: IntArray) {
val inputData = Data.Builder().putIntArray("ids", appWidgetIds).build()
val workRequest = OneTimeWorkRequestBuilder<WidgetUpdateWorker>().setInputData(inputData).build()
WorkManager.getInstance(context.applicationContext).enqueue(workRequest)
}
}
工作者:
class WidgetUpdateWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result {
val appWidgetIds = inputData.getIntArray("ids")
val appWidgetManager = AppWidgetManager.getInstance(applicationContext)
delay(200L) // Simulate network call. The behavior is the same with Retrofit and a real network call
appWidgetIds?.forEach { id ->
val views = RemoteViews(applicationContext.packageName, R.layout.new_app_widget)
views.setTextViewText(R.id.appwidget_text, "Setting text from worker")
appWidgetManager.updateAppWidget(id, views)
}
return Result.success()
}
}
应用程序小部件信息 XML:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_widget_description"
android:initialKeyguardLayout="@layout/new_app_widget"
android:initialLayout="@layout/new_app_widget"
android:minWidth="180dp"
android:minHeight="110dp"
android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen" />
作为结果,我在主屏幕上获得了一个不断闪烁和更新的小部件。这在模拟器和实际设备上都会发生。
我做错了什么?我正在针对API 30进行目标设置,并使用WorkManager版本
androidx.work:work-runtime-ktx:2.6.0
。