为什么我不应该使用消息总线来替代加载器和服务?

20
在典型的Android项目中,我们需要从某个地方(REST、SQL、缓存等)提取数据并以一种清晰的方式将其呈现到UI中。通常情况下,我们使用Loader、Service或(可能是)AsyncTask来实现这一点,但我认为这些方法都存在几个问题:
  • 它们很丑陋,特别是Loader,其API结构令人震惊
  • 很容易受线程干扰,同时也会影响UI线程
  • 我们的表示层代码被污染了Android代码和样板文件。我们经常将Android对象(如Cursors)传递到UI层,这使得难以实现清晰的架构。这迫使我们将业务领域特定的代码(最好是纯Java对象)与Android平台代码混合在一起,不利于可读性、维护、测试和未来开发的灵活性。实际上,我们经常会得到庞大而混乱的Activity/Fragment类。

我被这些文章中概述的思想所吸引: http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/ http://antonioleiva.com/mvp-android/ http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html

成功地使用MVP将Activities/Fragments/Views拆分为更小、更清晰的组件后,我现在认为解决上述问题的一个解决方案可能是依靠消息总线(Otto、EventBus等)而不是服务或加载器等与域数据交互。

因此,在实践中,这意味着我不会使用CursorLoader从数据库加载光标,而是使用消息总线发送消息以请求数据,响应该消息后台线程中加载数据,然后通过UI线程上的消息处理响应数据。对我来说,关键是我希望将数据结构从业务域而不是Android域强制转换出来,因此,我更喜欢业务对象的数组而不是光标。
由于这是工程,总会有权衡取舍,尽管这似乎提供了更清晰的职责分离,减少了loader/service模板代码,但有什么不足之处吗?
- 可能更难(尤其是对于新开发人员)理解代码 - 必须确保在正确的线程上发送和接收消息(Otto在此方面可能存在限制) - 必须避免将所有内容都实现为消息的诱惑,这最终将产生副作用 - 传递业务对象集合可能比使用像光标这样的对象效率低。虽然在许多情况下,这是否成问题? - 我不知道Otto / EventBus是否仅设计用于传递非常小的消息,或者是否适合传递较大的对象(例如业务对象的数组)。
我的问题是,在Android应用程序中采取这种基于消息的方法是否有任何根本性的原因不这样做?
3个回答

2
没有任何根本性的理由不采用基于消息传递的方法来开发Android应用。在我的实践中,我使用了像Loaders和AsyncTasks这样的“原始”工具(我不会将Services归类于此,因为其职责范围更广)。然后实现了总线功能,你猜怎么着?生活变得更加轻松、可预测,解耦程度也提高了。一旦我完全转向Rx,工作不仅更容易,而且更有趣!然而,没有任何东西可以使你免受处理生命周期的困扰。
所有这些只是实现细节,更重要的是保持整体清晰。当你谈论干净架构时,重要的是隐藏UI层(Activities、Fragments、Views等)如何以及从哪里获取对象。一旦你将这个特定的任务封装在用例中,使用哪个工具就不再重要:loaders、总线或Rx——你的UI层只需要遵循用例提供的接口——回调、事件或可观察对象。
我想指出两件事情:
1.每个层对用例实现的了解越少越好。
2.如果你选择了一个特定的工具来实现,那么在任何地方都要使用它。不要混合使用多种工具来完成同一项任务。

1

2
第一篇文章说:“因此,如果你的抽象并没有提供显著的好处,那么你应该避免使用它们”,所以更像是一个警告而不是禁止规则。第二篇(DI)似乎有点过时了,因为像 Dagger 这样的工具更加高效。最后一篇文章肯定看起来像是这种方法的缺点,但除非数据集很大或代码经常被调用(例如适配器),否则它足以抵消更清晰的代码带来的好处吗?我不太确定... - Ollie C

0
几年前,还没有强大的安卓设备,其内存为3GB或更多。当您从应用程序进行网络调用时,如果您的应用程序被中断,例如您接到电话并将应用程序发送到后台(如果您不使用服务),则您的应用程序将被终止,您的网络调用将浪费。如果您运行一个绑定了应用程序的服务,则您的应用程序将获得低优先级,以避免被Android OS杀死。
此外,使用服务可以使您的非UI工作或长时间运行的进程与UI线程分离。这对于非阻塞UI应用程序是一个好方法。您还可以处理方向更改。
现在,正如您所说,在Android Dev.世界中有一些其他选项(库、模式等),例如MVP、MVC、MVVM、Retrofit、OttoBus等。
我认为,开发Android应用程序没有确定的正确方式,例如“您必须使用MVP、Retrofit、服务、加载器、MVVM、数据绑定等”。
但是,在开发Android应用程序时,您可以考虑这些原则,并根据这些原则选择您的模式和库。 (原则的顺序可以根据您的项目、时间、资源等进行更改。)
1- Clean code
2- Seperate layers
3- Non Blocking Ui
4- Don't waste user's resources. (Avoid unneccassry network calls, memory allocation etc.)
5- Support orientation change.
6- Testing 
7- Clean Ui Design (Material Design)

这是一段老视频,但每个Android开发者都应该观看它: https://www.youtube.com/watch?v=xHXn3Kg2IQE


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接