在典型的Android项目中,我们需要从某个地方(REST、SQL、缓存等)提取数据并以一种清晰的方式将其呈现到UI中。通常情况下,我们使用Loader、Service或(可能是)AsyncTask来实现这一点,但我认为这些方法都存在几个问题:
由于这是工程,总会有权衡取舍,尽管这似乎提供了更清晰的职责分离,减少了loader/service模板代码,但有什么不足之处吗?
- 可能更难(尤其是对于新开发人员)理解代码 - 必须确保在正确的线程上发送和接收消息(Otto在此方面可能存在限制) - 必须避免将所有内容都实现为消息的诱惑,这最终将产生副作用 - 传递业务对象集合可能比使用像光标这样的对象效率低。虽然在许多情况下,这是否成问题? - 我不知道Otto / EventBus是否仅设计用于传递非常小的消息,或者是否适合传递较大的对象(例如业务对象的数组)。
我的问题是,在Android应用程序中采取这种基于消息的方法是否有任何根本性的原因不这样做?
- 它们很丑陋,特别是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应用程序中采取这种基于消息的方法是否有任何根本性的原因不这样做?