首页 \ 问答 \ Android Wear 2.0架构存在实时并发症问题(Android Wear 2.0 Architecture issues for realtime complications)

Android Wear 2.0架构存在实时并发症问题(Android Wear 2.0 Architecture issues for realtime complications)

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

该设置可能会导致心率,GPS坐标,小时,分钟,秒,dd / MM日期,dd / MM / yy日期,电池等并发症。

当我开始编程时,我发现了几个有问题的部分(很可能是因为这是我第一次发展并发症,或者是针对这个问题的Android应用程序的应用程序),因此也是这个问题。

请注意,这一行为可能特定于华为Watch 2 LTE。

1)升级间隔推/拉。

我理解数据提供者的复杂性,他们的唯一责任是将数据提供给任何正在呼叫他们的表盘。 这意味着我们不确定(并且我们依赖于表盘开发人员)了解并发症并相应地请求更新。 这会使一些并发症完全无用,如果不及时更新(例如显示秒)。 也可以留下显示旧数据的并发症(例如旧的GPS坐标,旧的心率bpm)。 好吧,我决定使用AlarmManager实现ProviderUpdateRequester数据送到表盘。 问题再次出现,并发症的发生速度应该会更快,就像秒钟一样,因为如果安排太频繁,Android会阻止未决意图。 所以为了解决这个问题,我决定在同一个服务实例中使用Android处理程序,因为下一个主题,这不是一个好主意。

2)并发症生命周期

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

3)显示感知服务

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

4)检测屏幕开/关

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

TL; RD

1)你如何确保表盘及时显示你的复杂情况,始终拥有正确和最新的信息?

2)如果每次onComplicationUpdate服务实例不同,你如何处理ComplicationProviderService繁重/冷启动?

3)长时间运行的服务显示器意识到一些疯狂的事情要做吗?

4)技术上,在环境模式下屏幕仍然Intent.ACTION_SCREEN_OFF ,为什么Intent.ACTION_SCREEN_OFF被广播? 当环境模式启用时,为什么Intent.ACTION_SCREEN_ON/OFF对称?

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

非常感谢


I'm developing a set of complications that I would like have regardless of the other installed apps and watch faces. Yes, at some point I am reinventing the wheel, but at the same time I am using this as a learning project. This will also ensure that I always have all the complications I use, available and that they all have the same format and style, instead of relying on 3rd party apps to provide them separately.

The set will have complications for Heart rate, gps coordinates, hours, minutes, seconds, dd/MM date, dd/MM/yy date, battery, etc.

When I started programing all this I found several problematic pieces (most likely because this is the first time I develop complications, or an app for android wear for that matter) and hence this question.

Note that some of this behavior might be specific to the Huawei Watch 2 LTE.

1) Upgrade interval push / pull.

I understand complications as data providers, whose only responsibility is to provide the data to whatever watch face is calling them. This means that we are not certain (and we rely on the watch face developer) to know about the complication and request updates accordingly. This turns some complications completely useless if not updated in time (for example display the Seconds). Could also leave to complications displaying old data (for example old GPS coordinates, old heart rate bpm). So ok, I decided to implement ProviderUpdateRequester with the AlarmManager to push data to the watch face. The problem again, is with complications that should happen faster, like seconds, as Android will block pending intents if they are schedule too often. So in order to get around that, I decided to use Android handlers within the same service instance, which turn out to be not a good idea because of the next topic.

2) Complication lifecycle

By debugging, I found out that the instance of the ComplicationProviderService object that is executing onComplicationActivated, onComplicationUpdate, onComplicationDeactivated can be different. This means that this is not a sticky service (single instance) that will be always running, but every update creates a new instance of the service. This is problematic because of heavy initialization complications: for example GPS, or Heart Rate monitor that need to listen for new values and it might take a while to retrieve the first value. And also, for those complications that can't rely on AlarmManager, and/or need to keep some sort of state between updates executions.

3) Display aware service

To get around the previous point , let's say you have static variables on your complication service , which are initialized onComplicationActivated and disabled at onComplicationDeactivated. For example, this could be getting a reference for the LocationProvider and starting listening for location updates. This will ensure that each invocation to onComplicationUpdate will not have to perform the heavy/cold initialization and will have access to the most up-to-date data. However, this also means that your logic will executed regardless if onComplicationUpdate is called or not. When in ambient mode (or screen off) the watch face can decide not to update the complication by not calling onComplicationUpdate, but it's not aware of our static logic, nor the ComplicationProviderService has a callback invocation for when the screen goes into ambient mode or turns on/off. This is a problem, because in our example, if the screen is off, we are still going to be listening for GPS coordinates, and most likely draining the battery. Sure, we can deal with this by using a combination of BroadcastReceiver (Intent.ACTION_SCREEN_ON/OFF) and DisplayManager.DisplayListener, but then again, not sure if i'm taking the correct path here, because this will mean that we are now creating services that need to be statically aware of the state of the display.

4) Detect screen on/off

The BroadcastReceiver for Intent.ACTION_SCREEN_ON/OFF works as expected when ambient mode is disabled, but it doesn't it's enabled. When ambient mode is enabled, Intent.ACTION_SCREEN_OFF is dispatched when going into ambient mode, but Intent.ACTION_SCREEN_ON is not dispatched when coming out of ambient mode. While a bit more complex, this can be accomplished by using DisplayManager.DisplayListener to get updates on the onDisplayChanged callback.

TL;RD

1) How do you ensure watch faces display your complications in a timely manner to always have correct and most up-to-date information?

2) How do you deal heavy/cold initialization of a ComplicationProviderService if everytime onComplicationUpdate is called the service instance is different?

3) Is making a long running service display-aware something crazy to do?

4) Technically the screen is still on when in ambient mode, so why is Intent.ACTION_SCREEN_OFF being broadcasted? Why isn't Intent.ACTION_SCREEN_ON/OFF symetrical when ambient mode is enabled?

5) Maybe complications shouldn't be use for exposing realtime information?

Thanks a lot


原文:https://stackoverflow.com/questions/48137450
更新时间:2022-07-17 18:07

最满意答案

目前还没有简单的方法可以做到这一点。 两个最简单的选择是

  1. 使当前的方法在语法上正确并保存。
  2. 打开其他浏览器。 如果您想要查看当前代码中的类或方法,可以使用cmd +单击它或使用“浏览它”,“实现者”,将打开另一个窗口的快捷方式。

同样在Pharo中,您可以使用GTSpotter快速找到您要查找的内容并预览其源代码


For now there is no easy way to do that. The two easiest opting are

  1. Make the current method syntactically correct and save it.
  2. Open another browser. If you want to see a class or method that is in your current code, you can cmd+click it or use "browse it", "implementors of", shortcuts that will open another window.

Also in you can use GTSpotter to quickly find what you are looking for and preview its source code

相关问答

更多
  • '世界菜单' - >'打开' - >'简单更换分拣机' 在右上窗格中,选择从中删除方法的类。 在中间窗格中,选择已删除的方法。 右键单击方法名称,调出一个菜单 选择“版本” 当版本工具出现时,选择最新版本(最新版本),即删除版本。 点击“恢复”按钮 当你浏览你的课程时,你会看到该方法已经恢复。 'World Menu'->'open'->'simple change sorter' In the top-right pane, select the class from which the method w ...
  • 首先,你的来源有问题。 Integer >> /方法看起来像这样: / aNumber "Refer to the comment in Number / " | quoRem | aNumber isInteger ifTrue: [quoRem := self digitDiv: aNumber abs "*****I've added abs here*****" neg: self negative ~~ aNumber negative. ...
  • 目前还没有简单的方法可以做到这一点。 两个最简单的选择是 使当前的方法在语法上正确并保存。 打开其他浏览器。 如果您想要查看当前代码中的类或方法,可以使用cmd +单击它或使用“浏览它”,“实现者”,将打开另一个窗口的快捷方式。 同样在Pharo中,您可以使用GTSpotter快速找到您要查找的内容并预览其源代码 For now there is no easy way to do that. The two easiest opting are Make the current method syntac ...
  • 要使工作区代码工作,请在延迟之前插入: World doOneCycle. 这将导致Morphic世界被重新显示。 请注意,这是一个快速且非常脏的黑客,而不是正确的方法(请参阅我的其他答案)。 延迟会阻止整个UI过程,而Morphic的重点在于,您可以在执行代码时同时执行许多操作。 To make your workspace code work insert this before the delay: World doOneCycle. This will cause the Morphic wor ...
  • 正如@LeandroCaniglia指出的,你不应该比较块。 在不比较块的情况下,有两种方法可以解决您的问题: 初始化变量nil 。 在你的访问器方法中,你懒惰地初始化它: toRunBlock ^ toRunBlock ifNil: [ [] ] 现在,当您查看变量toRunBlock ,除非已发送#toRunBlock或通过其他方式设置了块,否则#toRunBlock nil 。 你的代码将变成: toRunBlock ifNil: [ "Run some code if toRunB ...
  • 看看方法ArrayedCollection类>> new。 它会覆盖new来调用new:0作为参数。 这将替换调用initialize的Behavior中的new的默认实现。 如果您真的想这样做,请在您的类中实现new和new:作为类方法。 在每种情况下,调用super然后调用initialize。 new ^super new initialize new: sizeRequested ^(super new: sizeRequested) initialize 说了这么多,从Array子 ...
  • 未经测试,但是: Smalltalk allClasses do: [:each | each fileOut] 这应该转储300万个.st文件,以系统中的每个类命名。 欢迎和快乐的小徒步! 编辑:看起来,这在早期的吱吱声中不起作用,我一直在测试,看起来以下应该在Scratch源代码图像中起作用: SystemOrganization categories do: [:each | SystemOrganization fileOutCategory: each] Untested, but: Smal ...
  • 您可以双击任何类以在该特定类上打开层次结构浏览器 。 工具栏中的层次结构按钮和菜单项浏览层次结构 (Ctrl + H)打开相同的视图。 继承浏览器向您显示当前所选方法的分层实现。 单击工具栏中的继承按钮。 此外,还有协议浏览器可以同时显示类的所有方法和超级方法。 要打开此浏览器,请在类的上下文菜单中选择浏览协议 (Ctrl + Shift + P)。 You can double-click on any class to open a Hierarchy Browser on that particula ...
  • 虽然Store的结构不是分布式工具,但可以这种方式使用。 大多数从事VisualWorks和ObjectStudio工作的工程师都使用本地存储库(在他们的办公室;大部分团队都在地理位置上分布)。 有合并和复制工具,允许他们根据需要/期望将他们的本地工作与“记录存储库”同步。 话虽如此,大众汽车有一个Monticello港口(因此也适用于ObjectStudio)。 唯一真正的问题是,在发布后,它不会与工具(浏览器)“谈论”发布状态。 那是因为它主要用于维护Seaside端口,而不是大众的主线版本工具。 Wh ...
  • 将消息发送到对象由VM处理,您将找不到处理它的特定方法。 但是, ContextPart>>#send:to:with:super:包含的实现应该与VM的实现方式相同。 特别是,它调用Behavior>>#lookupSelector: ,在那里你可以看到爬上继承层次结构的代码。 Sending a message to an object is handled by the VM, you won't find the specific method that handles it. However, C ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。