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

时间:2015-02-20 12:55:53

标签: android android-service android-testing android-cursor android-cursorloader

在我们需要以干净的方式将数据从某个地方(REST,SQL,缓存等)提取到UI的典型Android项目中,我们通常使用Loader,Service或(可能是yuk)AsyncTask,但我发现由于以下几个原因,所有这些方法都不能令人满意:

  • 它们很难看,尤其是具有令人震惊的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将活动/碎片/视图分解为更小/更清洁的部分,我现在认为上述问题的解决方案可能是依赖于消息总线(Otto,EventBus等)而不是服务或加载器或与域数据交互的任何内容。

所以在实践中这意味着不是使用(例如)CursorLoader从数据库加载Cursor,而是使用消息总线发送消息来请求数据,数据加载到后台线程响应该消息,然后在通过UI线程上的消息到达时处理响应数据。对我来说至关重要的是,我更倾向于将数据结构从业务领域推出,而不是Android域,所以我更喜欢业务对象数组,而不是Cursor。

这种工程设计总是需要权衡,虽然这似乎提供了更清晰的关注点分离,但是装载机/服务样板的减少程度较低,有什么缺点?

  • 理解代码可能更难(特别是对新开发人员而言)
  • 有必要确保在正确的线程上发送和接收消息(Otto似乎在这里可能有限制)
  • 有必要避免将所有事情都作为信息实施的诱惑,这最终会适得其反。
  • 传递业务对象集合可能不如使用像Cursors这样的对象。虽然在许多情况下它在实践中是一个问题吗?
  • 我不知道Otto / EventBus是否只是为了传递非常小的消息,或者是否适合传递更大的对象(例如业务对象数组)。

我的问题是,有没有基本的理由不采用这种基于消息的方法与Android应用程序?

3 个答案:

答案 0 :(得分:2)

  

任何基本原因不使用Android应用程序采用这种基于消息的方法

我猜没有。在我的实践中,我使用了诸如Loaders和AsyncTasks之类的'stock'之类的东西(我不会把服务放在这一行,因为它的责任范围更广)。然后实施了公共汽车的事情,猜猜什么?生活变得更容易,更可预测,脱钩增加了。一旦我完全搬到Rx,工作变得不仅容易,而且更有趣!但是,没有什么可以帮助你免于处理生命周期。

所有这些只是实施细节,更重要的是要保持全球事物的清晰。当你谈到清洁架构时,问题是隐藏UI层(活动,碎片,视图......)对象的来源和位置。一旦你将这个特定工作封装在用例中,使用哪个工具就不是什么大事了:加载器,总线或者Rx - 你的UI层应该只停留在用例提供的接口上 - 回调,事件或者可观察的

我指出两件事:

  1. 任何层知道usecase实现越少越好。
  2. 如果您选择了一个特定的工具来实现,请在任何地方使用它。不要为同一份工作混合使用多种工具。

答案 1 :(得分:1)

他们 为他们对这些方法的抵制提供了解释:

1。 Be careful with code abstractions

2。 Avoid dependency injection frameworks

3。 Avoid Creating Unnecessary Objects

4。 Avoid Internal Getters/Setters

答案 2 :(得分:0)

几年前,没有强大的Android设备有3 GB或更多。当您从应用程序进行网络呼叫并且您的应用程序受到中断时,例如您接到电话并将您的应用程序发送到后台(如果您不使用服务),您的应用程序将被终止并浪费您的网络呼叫。如果您的应用程序绑定了正在运行的服务,那么您的应用程序将获得被Android操作系统杀死的低优先级

同样通过服务,您可以从ui-thread中分离出非ui作品或长时间处理过程。对于非阻止ui app来说,这是一个很好的方法。您也可以处理方向更改。

现在正如你所说,Android Dev中还有其他一些选项(库,模式等)。世界,如MVP,MVC,MVVM,Retrofit,OttoBus ......

我认为开发Android应用程序并不是一种正确的方法,例如&#34;你必须使用MVP,Retrofit,服务,加载器,MVVM,数据绑定等。&#34; < / p>

但是,当您开发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