- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个小部件,如 this guide 中所述,
…If your widget setup process can take several seconds (perhaps while performing web requests) and you require that your process continues, consider starting a Task using WorkManager in the onUpdate() method.
onUpdate
中的工作请求排入队列方法,我没完没了
onUpdate
大约每半秒调用一次,传入相同的 Intent 。我尝试使用
goAsync()
更新小部件和
GlobalScope.launch
对于我的网络请求,它工作得很好。但是,建议使用 workmanager api 进行 i/o 工作,这就是我想要做的。
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)
}
}
worker :
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" />
结果,我在主屏幕上看到一个不断闪烁和更新的小部件。这也发生在模拟器和真实设备上。
androidx.work:work-runtime-ktx:2.6.0
最佳答案
我找到了一些关于这个问题的信息,我想我现在会回答我自己的问题。
为什么会发生这种情况
根据replies on the issue tracker ,这是预期的行为。当没有待处理的工作时,WorkManager 会禁用其内部 RescheduleReceiver
,并且组件的状态更改触发 onUpdate
. onUpdate
然后将另一个工作请求排入队列,我们最终陷入无限循环。我也推荐阅读CommonsWare's post其中详细介绍了这一点。
推荐库开发人员的解决方案是不要“无条件地将工作排入 onUpdate
”。这可能很难实现,而且由于我没有时间尝试这个建议,我将在下面提供一个对我有用的解决方法。
解决方法
到目前为止,我发现的最简单的解决方法是在 AppWidgetProvider 的 onEnabled
中设置一个 future 很远的虚拟工作请求。这样总有一个待处理的工作请求。例如:
override fun onEnabled(context: Context) {
val alwaysPendingWork = OneTimeWorkRequestBuilder<YourWorker>()
.setInitialDelay(5000L, TimeUnit.DAYS)
.build()
WorkManager.getInstance(context).enqueueUniqueWork(
"always_pending_work",
ExistingWorkPolicy.KEEP,
alwaysPendingWork
)
}
override fun onDisabled(context: Context) {
WorkManager.getInstance(context).cancelUniqueWork("always_pending_work")
}
不要忘记每个 AppWidgetProvider 必须提供唯一的工作名称。
"${YourWorker::class.simpleName}_work"
对我来说效果很好。
关于android - 从 AppWidgetProvider 启动 WorkManager 任务会导致无休止的 onUpdate 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70654474/
我正在 CSS 和 JS 中使用 Canvas 上的 DOM 创建一个类似小行星的简单游戏,用于……实验目的。 在这个例子中我的代码非常小,可以很容易地看到下面发生了什么。最终目标:让箭头键顺畅地旋转
我是一名优秀的程序员,十分优秀!