如何在Android 8.0中正确更新小部件-Oreo-API 26 [英] How To Properly Update A Widget In Android 8.0 - Oreo - API 26

查看:246
本文介绍了如何在Android 8.0中正确更新小部件-Oreo-API 26的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,我有一个用于targetSDKVersion设置为26的应用程序的小部件.此小部件需要100毫秒至10秒钟的时间进行更新.大部分时间都在1秒以下.在Android O之前,如果在我的AppWidgetProvider上调用了onUpdate(),则可以启动后台服务来更新此小部件.但是,如果您尝试执行此行为,则Android O返回IllegalStateException.启动前台服务的明显解决方案似乎是一种极端的措施,可以在99%的时间内不到10秒的时间内完成操作.

Let's say I have a widget for an app that has targetSDKVersion set to 26. This widget takes between 100ms and 10s to update. Most of the time under 1s. Before Android O, if onUpdate() was called on my AppWidgetProvider, I could launch a background service to update this widget. However, Android O returns an IllegalStateException if you attempt that behavior. The obvious solution of starting a foreground service seems like an extreme measure for something that will be done in under 10s 99% of the time.

可能的解决方案

  • 启动前台服务以更新窗口小部件.会在10秒钟内消失的通知使用户烦恼.
  • 使用JobScheduler尽快安排作业.您的小部件可能会在一段时间内更新,也可能不会更新.
  • 尝试在广播接收器中进行工作.锁定其他任何应用程序的UI线程.好吧.
  • 尝试在小部件接收器中进行工作.锁定其他任何应用程序的UI线程.好吧.
  • 滥用GCM来运行后台服务.很多工作,而且感觉很棘手.

我个人不喜欢上述任何一种解决方案.希望我缺少一些东西.

I don't personally like any of the above solutions. Hopefully I'm missing something.

(更令人沮丧的是,我的应用程序已经被系统调用onUpdate()加载到内存中.我看不到如何将我的应用程序加载到内存中以调用onUpdate(),但是没有给我的应用程序1s更新UI线程中的小部件可以节省任何人的电池寿命.)

(Even more frustrating is that my app is already loaded into memory by the system calling onUpdate(). I don't see how loading my app into memory to call onUpdate(), but then not giving my app 1s to update the widget off the UI thread is saving anyone any battery life.)

推荐答案

您没有说明更新触发机制是什么.您似乎担心延迟(您的窗口小部件可能会或可能不会更新一会儿"),因此我将假定您的担心与用户与应用程序窗口小部件的交互(例如,点击按钮)有关.

You don't indicate what the update trigger mechanism is. You seem concerned about latency ("Your widget may or may not get updated for a while"), so I am going to assume that your concern is tied to user interaction with the app widget, such as tapping a button.

使用JobScheduler尽快安排作业.您的小部件可能会在一段时间内更新,也可能不会更新.

Use JobScheduler to schedule a job as quickly as possible. Your widget may or may not get updated for a while.

这是"use JobIntentService"的一种变体,对于这种情况,建议使用AFAIK解决方案.

This is a variation on "use JobIntentService", which AFAIK is the recommended solution for this sort of scenario.

其他选项包括:

  • getForegroundService()PendingIntent一起使用.这样,您可以有效地发誓",您的服务将在ANR时间范围内调用startForeground().如果工作时间超过几秒钟,请致电startForeground()以确保Android不会感到胡思乱想.这应该使前台通知出现的时间最少.而且,如果用户轻按了一个按钮,而几秒钟后您仍在忙于工作,那么您可能会想要显示通知,或者采取其他措施让用户知道他们仍然在要求什么进行中.

  • Use getForegroundService() with PendingIntent. With this, you effectively "pinky swear" that your service will call startForeground() within the ANR timeframe. If the work takes longer than a few seconds, call startForeground() to ensure that Android doesn't get cranky. This should minimize the number of time the foreground notification appears. And, if the user tapped a button and you are still busy doing work a few seconds later, you probably want to show a notification or otherwise do something to let the user know that what they asked for is still in progress.

使用BroadcastReceiver上的goAsync()在接收者的上下文中进行工作,同时不占用主应用程序线程.我还没有在Android 8.0+上尝试过,所以是YMMV.

Use goAsync() on BroadcastReceiver, to do work in the context of the receiver while not tying up the main application thread. I haven't tried this with Android 8.0+, so YMMV.

这篇关于如何在Android 8.0中正确更新小部件-Oreo-API 26的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆