Android:将观察者模式与视图一起使用(可能与 MVC、MVVM 相关)
我花了几个小时阅读有关在 Android 中实现各种 MVC 类型模式的各种问题和答案。我在各种博客中看到了一些代码示例。然而,我仍然感谢一些关于我想要实现的目标的想法和意见。具体来说,我想制定出最佳的代码机制来通知单个视图或一组视图特定的数据项已更改。
我的应用程序非常简单,它通过蓝牙从硬件设备获取测量数据,并显示和记录该数据。目前,我有一项服务负责蓝牙通信和后台日志记录。我有一个“全局”数据存储类,它是应用程序的扩展。
当从外部设备轮询测量数据时,测量数据(实际上是大约 30 个字节的数据)在数据存储对象(用 MVC 术语来说,我猜是“模型”)中更新。
在任何时候,UI 视图都只会显示该数据的一小部分。通常,给定的视图仅对表示测量数据的一个特定字节感兴趣。当用户移动到不同的 Activity 类时,将显示其他视图,这些视图将显示该数据的不同子集。
因此,为了达到这一点,我尝试选择最佳方法,以便在给定数据项发生更改时在感兴趣的视图上调用 invalidate()
。
选项似乎是:
利用现有的 Observer 类和相关类。
通过在数据模型中创建我自己的 register() 和 unregister() 函数,实现一种“滚动我自己”的观察者模式。观察者视图将保存在 ArrayList 中(或者可能是每个数据项一个观察者列表的更复杂的排列)。每次更新数据时,我都会循环遍历此 ArrayList 并调用
invalidate()
(当然,也可以调用postInvalidate()
,具体取决于我的线程安排)。
有什么理由让我应该使用上述其中一种而不是另一种?我还应该考虑其他“观察者”机制吗?
I've spent some hours reading various questions and answers regarding implementing the various MVC-type patterns in Android. I've seen a few code examples posted in various blogs. I would, however, still appreciate some ideas and opinions on what I am trying to achieve. Specifically, I'd like to work out the best code mechanism to inform a single View, or a group of Views, that a particular item of data has been changed.
My application is quite simply one which obtains measurement data from a hardware device via Bluetooth, and displays and logs that data. At present, I have a Service which takes care of Bluetooth communications and background logging. I have a 'global' data store class that is an extension of Application.
As measurement data is polled from the external device, the measurement data (which is in reality about thirty bytes of data) is updated in the data store object (which, in MVC terms, I'm guessing is the 'model').
At any time, only a small subset of that data will be displayed by UI Views. Typically, a given View will only be interested in representing one particular byte of measurement data. As the user moves to different Activity classes, other Views will be displayed which would display a different subset of that data.
So to get to the point, I'm trying to choose the best way to cause invalidate()
to be invoked on interested Views when a given data item is changed.
The options seem to be:
Make use of the existing Observer class, and related classes.
Kind of 'roll my own' observer pattern, by creating my own register() and unregister() functions in the data model. Observer Views would be held in an ArrayList (or perhaps a more complex arrangement of one observer List per data item). I'd loop through this ArrayList each time data are updated and call
invalidate()
(orpostInvalidate()
of course, depending on my threading arrangement).
Are there any reasons why I should use one of the above over the other? And is there any other 'observer' mechanism I should consider?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Android 中的许多视图都由
BaseAdapter
< 的某些子类支持/a> 有一个方法notifyDataSetChanged()
指示视图自行刷新。如果您使用的是视图(例如ListView
或GridView
或任何后代<一href="http://developer.android.com/reference/android/widget/AdapterView.html" rel="nofollow">AdapterView
) 然后它由 BaseAdapter 支持并且您只需更新该适配器,视图就会自行刷新。我想这意味着,我投票支持你使用内置的观察者模式。如果您使用自定义视图,那么显然这不起作用,并且无论如何您都必须使用自定义刷新方法。
Many views in Android are backed by some subclass of
BaseAdapter
which has a methodnotifyDataSetChanged()
which instructs the view to refresh itself. If you are using a view (such asListView
orGridView
or any descendent ofAdapterView
) then it is backed by a BaseAdapter and you can simply update that Adapter and the view will refresh itself.I guess this means, I vote that you use the built-in observer pattern. If you are using a custom view then obviously this won't work and you would have to use a custom method of refreshing anyway.
另一种选择是使用 Android Intent 框架。当服务中收到新数据时,将数据设置为通用模型,并使用 Context.broadcastIntent(Intent) 方法广播数据已更新的意图。任何对该数据感兴趣的视图都可以使用 Context.RegisterReceiver(Receiver) 和 Context.unregisterReceiver(Receiver) 方法注册和取消注册接收器。从那里,视图将从通用模型中检索数据并相应地更新视图。
我认为这可能是 Android.Lifecycle.Observer 包中的观察者模式在幕后所做的事情。
Another Option would be to use the Android Intent framework. When new data is received in the service set the data to the universal model and broadcast an intent that the data has been updated using the Context.broadcastIntent(Intent) method. Any view that is interested in that data would register and unregister receivers using the Context.RegisterReceiver(Receiver) and Context.unregisterReceiver(Receiver) methods. From there the view would retrieve the data from the universal model and update the view accordingly.
I think this might be what the observer pattern in Android.Lifecycle.Observer package is doing behind the scenes.