5670a9ddf0babad113c5caeabb8c9456
雕虫晓技(八) Android与数据流的斗争

本文并没有什么实质性的内容,只是自己工作和学习这段时间的一些经验杂谈,仅从自己的角度阐述一下自己观察到的一些内容,可能并不全面,也不一定正确,仅供大家参考一下。

目前 Android 开发,从广义上来说可以划为前端的一部分,毕竟大部分 Android 开发所做的工作就是从服务器获取数据,将这些数据用合适的方式展示给用户,再把用户操作产生的数据传递给服务器。在这样的情境下 Android 开发所需要解决的一个核心问题就是数据的传递,如何把服务器与页面内容关联起来,并且保持同步。相信对于这一过程,每一个工程师都有自己的解决方案。这一个过程看似简单,但真正想要将其比较完美的实现,却也需要花费一番功夫。

蛮荒时代

在 Android 开发还未成熟,处于蛮荒时期的时候,没有成型方案作为参考,此时比较常见的做法就是在 Activity 里创建线程,在线程内发送网络请求,之后用 Handler 把请求结果传递到主线程,主线程收到信息后更新页面,这种方式缺陷是十分明显的,它会造成 Activity 十分臃肿,随着项目的发展会变成一团乱麻。

网络库

后来出现了诸多成型的网络的封装库,因此网络请求的核心逻辑就不在 Activity 中了,这为 Activity 减轻了不少负担,但是此时又一个问题出现了,那就是如何从请求库获取网络请求的返回结果,此时大多数网络库都采用了一个最容易想到的方案,那就是 Callback,Activity 发出请求时会得到一个 Callback,并通 Callback 回调得到最终的网络请求结果。

数据层

但是网络请求问题解决了,但是很快另一个问题又成了比较困扰的内容,例如:网络请求得到的结果并不能直接使用,需要进行一些数据的转换,又或者网络请求并不需太高的实时性,请求一次后需要缓存起来,避免多次重复请求。这样在 Activity 中就需要一些数据转换操作,或者进行一些数据库相关的操作,很快 Activity 又会变得臃肿起来。

为了避免在 Activity 中直接进行这些操作而变得臃肿,很多人不得不在网络请求和 Activity 之间封装一个数据层,Activity 向数据层请求数据,数据层根据需要从网络或者数据库获取数据并且对数据进行转换,然后交给 Activity。此时数据需要如何传递呢?

Activity <--callbac-1-- 数据层 <--callback-2-- 网络请求

通常来说需要 Activity 向数据层发送请求时附带一个 Callback,而数据层直接向网络发出请求时又是另外一个 Callback,需要把数据从一个 Callback 传递到另一 Callback,当然这是对于一些比较简单的业务,如果业务更加复杂一点,可能会划分更多的层和节点,那么就不仅仅是两个 Callback 了,数据需要多在多个 Callback 之间流动,Callback 太多就会导致逻辑不是那么清晰,当项目大到一定程度时,里面的各种 Callback 就能把人绕晕。

EventBus

为了解决错综复杂的 Callback 问题,EventBus 诞生了,它的核心其实就是发布订阅模式,当 Activity 需要获取一些信息时,发送一个事件(Event), 数据层接收到 Event 后执行相关操作,之后同样通过发送 Event 告诉 Activity 最终的结果。此时各个组件之间不需要再去关心各种错中复杂的数据传递方式,只需要把需要传递的数据包装成一个个的 Event 再通过 EventBus 发送出去,如果需要相关的事件的话,就在合适的位置注册一下监听该事件。

所谓事件总线,就是把所有的事件都通过一个地方进行传递,这个和计算机硬件上的总线原理类似,因此也就被称为“事件总线”,在我最初接触到这种思想时,确实也被惊艳了一下,这种方式在一定程度上解决了过多 Callback 的问题,让代码看起来更加简洁了。

但是这种方式也并不是完美无缺的,它的确让代码更加简洁了,但是它将数据传递的过程隐藏起来了,相当于切断了数据流的追踪线路,增大了数据流追踪的难度,如果整个项目都是自己设计或者一开始就参与的问题倒是不大,但是如果是接手别人的项目是这样设计的,那么接手的人很可能会一脸懵逼。

例如:我需要当前的用户的信息,也知道通过哪个 Event 来接收这一信息,但是我发现接收到的信息有时是错误的,因此我需要找到发送该信息的位置并修改这一错误,这时就比较麻烦了,因为所有信息都是通过 EventBus 发送的,但我无法通过 EventBus 直接追踪到发送位置,因此我需要找到该 Event ,并追踪这个 Event 都被哪些地方使用了,然后从这些地方中筛选出时哪里发送了这个错误信息,对于一个庞大的项目来说,这一工作量无疑是巨大的,假若前人在多个地方都发送了这一个 Event,我则需要对所有发送过这个 Event 的地方都进行检查,这会浪费大量的工作时间。因此在实际的公司项目上我很少采用 EventBus 这一方案,尽管它很好用,但是这一点缺陷就足以致命。

数据流

正在我纠结到底如何传递数据时,Rx 技术方案就出现在了我的面前,Rx 的核心思想就是响应式编程,即一种面向数据流和变化传播的编程范式,数据更新是相关联的。 这种思想和 Linux 中的管道也是类似的,数据从一个地方进入转换后输出,而这个输出恰好是另一段处理的输入,就这样把数据串联起来。

top Created with Sketch.