Android 实时并发症的 Wear 2.0 架构问题

Android Wear 2.0 Architecture issues for realtime complications

我正在开发一套我想要的复杂功能,无论其他已安装的应用程序和表盘如何。是的,在某些时候我正在重新发明轮子,但同时我将其用作学习项目。这也将确保我始终拥有我使用的所有复杂功能,并且它们都具有相同的格式和样式,而不是依赖第 3 方应用程序单独提供它们。

该套装将具有心率、gps 坐标、小时、分钟、秒、dd/MM 日期、dd/MM/yy 日期、电池等方面的复杂功能。

当我开始对所有这些进行编程时,我发现了几个有问题的部分(很可能是因为这是我第一次开发并发症,或者是 android 磨损的应用程序),因此出现了这个问题。

请注意,其中一些行为可能特定于 Huawei Watch 2 LTE。

1) 升级间隔推送/拉取。

我将复杂性理解为数据提供者,他们的唯一职责是将数据提供给调用它们的任何表盘。这意味着我们不确定(并且我们依赖表盘开发人员)了解复杂功能并相应地请求更新。如果不及时更新(例如显示秒),这会使一些复杂功能完全无用。也可能留给显示旧数据的并发症(例如旧的 GPS 坐标、旧的心率 bpm)。 好吧,我决定用 AlarmManager 实现 ProviderUpdateRequesterpush 数据到表盘。问题又来了,并发症应该发生得更快,比如几秒钟,因为 Android 如果安排得太频繁,将阻止未决的意图。因此,为了解决这个问题,我决定在同一个服务实例中使用 Android 处理程序,由于下一个主题,这并不是一个好主意。

2) 并发症生命周期

通过调试,我发现ComplicationProviderService对象执行onComplicationActivatedonComplicationUpdateonComplicationDeactivated的实例可以不同。这意味着这不是一个始终 运行 的粘性服务(单个实例),而是每次更新都会创建一个新的服务实例。这是有问题的,因为初始化很复杂:例如 GPS 或需要侦听新值的心率监视器,并且可能需要一段时间才能检索到第一个值。而且,对于那些不能依赖 AlarmManager 的并发症,and/or 需要在更新执行之间保持某种状态。

3) 显示感知服务

为了绕过前一点,假设您的并发症服务上有静态变量,这些变量在 onComplicationActivated 初始化并在 onComplicationDeactivated 处禁用。例如,这可能是获取 LocationProvider 的引用并开始侦听位置更新。这将确保对 onComplicationUpdate 的每次调用都不必执行 heavy/cold 初始化,并且可以访问最新的数据。 但是,这也意味着无论 onComplicationUpdate 是否被调用,您的逻辑都会执行。 当处于环境模式(或屏幕关闭)时,表盘可以通过不调用 onComplicationUpdate 来决定不更新复杂功能,但它不知道我们的静态逻辑,ComplicationProviderService 也没有回调调用屏幕进入微光模式或变为 on/off。这是一个问题,因为在我们的示例中,如果屏幕关闭,我们仍将监听 GPS 坐标,并且很可能会耗尽电池电量。 当然,我们可以通过结合使用 BroadcastReceiver (Intent.ACTION_SCREEN_ON/OFF) 和 DisplayManager.DisplayListener 来处理这个问题,但是话又说回来,不确定我在这里走的路是否正确,因为这意味着我们现在正在创建需要静态了解显示状态的服务。

4) 检测屏幕on/off

Intent.ACTION_SCREEN_ON/OFFBroadcastReceiver 在禁用环境模式时按预期工作,但它没有启用。启用环境模式后,进入环境模式时会调度 Intent.ACTION_SCREEN_OFF,但退出环境模式时不会调度 Intent.ACTION_SCREEN_ON。虽然有点复杂,但可以通过使用 DisplayManager.DisplayListener 获取 onDisplayChanged 回调的更新来完成。

TL;RD

1) 您如何确保表盘及时显示您的复杂功能以始终获得正确和最新的信息?

2) 如果每次 onComplicationUpdate 调用的服务实例都不同,您如何处理 heavy/cold 初始化 ComplicationProviderService

3) 做一个很长的 运行 服务显示感知是不是很疯狂?

4) 从技术上讲,在环境模式下屏幕仍然亮着,那么为什么要播放 Intent.ACTION_SCREEN_OFF?为什么在启用环境光模式时 Intent.ACTION_SCREEN_ON/OFF 不对称?

5) 也许并发症不应该用于公开实时信息?

非常感谢

有几件事情要解包:

  • 并发症并不意味着要经常更新(想想几分钟,而不是几秒钟)- 这是为了节省电量。
  • ProviderUpdateRequester 更适合(平均不频繁)不定期更新,例如通过聊天应用程序发送的消息。
  • 时间相关并发症 - 没有 "update" 本身,但 Wear 为开发人员提供了从特定时间开始向上/向下计数以及显示日期相关字段(世界时钟、月份日期)的方法,无需提供商一直在发送系统更新。对于最后一个,请参阅 ComplicationText.TimeDifferenceBuilder 的文档 和 ComplicationText.TimeFormatBuilder.

对于您的用例,更合适的做法可能是考虑 always-on app。用户出于特定目的在特定时间段内使用它,因此他们明确同意使用更多电池来跟踪 GPS 或心率等内容。例如,Wear 上的很多 运行 应用都是这样做的。

希望对您有所帮助。