不请自来,见谅。 评价某种方式优劣,有很多种指标,包括空间、时间等性能因素,还有代码的复杂程度,同整个程序的相性等等。 一般 认为本地广播是三种方式中消耗时间、空间最多的一种方式,但也是同 android 相性最好的方式。因为广播属于 android 四大组件之一,在 BroadcastReceiver 中的 onReceive 方法中可以获得 Context、Intent 参数。持有这两个参数便可以调用许多 android sdk 中的方法,这一优势另外两种方式很难弥补的,无论是 EventBus 还是观察者,需要获得 Context 的话,往往都需要进行复杂的参数传递或者是依赖注入。 本地广播另外的一个优点是,许多系统级的事件都是使用广播来进行通知的,像常用的电量变化、网络状态变化、短信发送接收的状态等等。这就使得与 android 系统相关的通知,广播往往成了唯一的选择。 但这并不意味着 android 系统中的通知都应该使用广播,因为相对于其它的方式而言,广播是重量级的、消耗资源较多的方式。广播的优势体现在它与 android sdk 链接的更紧密,当我们需要同 android 交互的时候,广播提供的便捷性抵消掉了它过多的资源消耗。但是对于不需要同 android 交互或是只做很少的交互的时候,使用广播往往是一种浪费。 并 且在广播中有一个常见的坑:错误的使用 BroadcastReceiver 的 Context。在 android 的 Application、Activity、Service、ContentProvider、BroadcastReceiver 中都可以获得对应的 Context,但它们并不完全相同。Activity 的 Context 所能做的事是最全的,而其它组件中的 Context 都或多或少的有着功能残缺。就拿常见的弹出 Dialog 来说,不知道有多少新手试图使用非 Activity 的 Context 创建 Dialog 最终无功而返。另外,使用 BroadcastReceiver 等非 Activity 组件的 Context 启动 Activity 也有可能造成隐蔽的错误:当使用非 Activity 组件的 Context 启动 Activity 时,如果不指定 flag 的话,默认会创建一个新的 task,而使用 Activity 的 Context 并且不指定 flag 的话,默认会使用原 task。 Dave smith 的博客中有 一篇文章 详细的介绍了各种 Context 的区别: ![]() EventBus 作为 Android 开发中常用的框架,拥有着许多优点:
EventBus 的缺点主要集中在它现阶段的实现方式,2.4.0 版是利用反射来实现的(貌似以前的版本也是? )。在 Subscriber 注册的时候,Subscriber 中的方法会被遍历查找以 onEvent 开头的 public 方法。这将带来一些问题,一旦对代码进行混淆,就无法查找到了,所以一个程序既用到了 EventBus 又需要进行代码混淆时,就得设置混淆规则:
观 察者这种设计模式应当属于程序员的基本功,由于观察者的实现比较简单,因此性能上是三者中最好的,但观察者难以控制通知的优先度,特别是一开始没有考虑优 先度中途更改需求又加入优先度。另外观察者模式要求观察者在事件发生时在场才能收到通知,这就使得观察者有可能遗漏事件,一般来说这并不是问题,但是当程 序要求观察者不能遗漏事件时那就坑了。客观来说,这并不能算作观察者的缺点,因为其它的方式往往也是这样,更加严谨的说法是观察者没有 Eventbus 优先级、粘滞事件的优点。 但有一个缺点是观察者独有的,那就是观察者可能会造成接口的膨胀。特别是当程序要求大量形式各异的通知,而程序员有没有做出良好的抽象时,代码中会包含大量的接口,接口数量的增长又会带来命名、注释等等一大堆问题。本质上说观察者要求程序员从零开始实现事件的产生、分发与处理过程,这就要求参与者必须对整个通知过程有着良好的理解。当程序代码适量时,这是一个合理的要求,然而当程序太大时,这将成为一种负担。 综上来看,广播、EventBus、观察者这三种方式有着它们各自优缺点,具体使用哪一种还是得依靠具体的情况。说了半天感觉什么都没有说,摔... |
|