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

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

问题描述

假设我有一个应用的小部件,其 targetSDKVersion 设置为 26.这个小部件需要 100 毫秒到 10 秒的时间来更新.大部分时间在 1s 以下.在 Android O 之前,如果在我的 AppWidgetProvider 上调用 onUpdate(),我可以启动一个后台服务来更新这个小部件.但是,如果您尝试该行为,Android O 会返回 IllegalStateException.启动前台服务的明显解决方案似乎是一种极端措施,可以在 10 秒内完成 99% 的时间.

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.

这是使用 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天全站免登陆