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

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

  • 它们很难看,尤其是具有令人震惊的API结构的Loaders
  • 它很容易被包裹在线程中,并踩在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应用程序?

  • 如何使用Android uiautomator填写密码EditText?
  • 如何在Android Unit测试中打开控制台输出?
  • 如何将Android(instrumentation)测试文件放在项目目录之外?
  • 无法让Robotium在Android Studio中运行
  • Gradle:如何在控制台中显示androidTest结果?
  • unit testingnetworking响应。 debugging时工作,而不是实际运行时
  • 在Android中测试GPS
  • 启动活动进行测试
  • 任何基本原因都没有采用这种基于消息的方法与Android应用程序

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

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

    我指出两件事:

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

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

    1. 注意代码抽象

    2. 避免dependency injection框架

    3. 避免创建不必要的对象

    4. 避免内部吸气/安装者

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

    此外,通过服务,您可以从ui-thread中分离出非ui作品或长期作品。 对于非阻塞ui app来说这是一个很好的方法。 您还可以处理方向更改。

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

    我认为开发Android应用程序没有一定的正确方法,例如“你必须使用MVP,改造,服务,加载器,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) 

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