关于什么是ioc,看下这篇文章,写得很详细
http://blog.csdn.net/wanghao72214/article/details/3969594
关于ioc,现在有两个开源的, 在github上有,简单介绍看下面。通过发布/订阅事件解耦事件发送和接受,从而简化应用程序组件(Activities, Fragments及后台线程)之间的通信
EventBus
-
greenrobot的开源项目
项目地址:https://github.com/greenrobot/EventBus
文档介绍:https://github.com/greenrobot/EventBus#general-usage-and-api
特点:(1) 支持在不同类型的线程中处理订阅,包括发布所在线程,UI线程、单一后台线程、异步线程
(2) 支持事件优先级定义,支持优先级高的订阅者取消事件继续传递,支持粘性事件,是不是跟系统的有序广播、粘性广播很像啊
(3) 不是基于annotations
(4) 性能更优
(5) 体积小
(6) 支持单例创建或创建多个对象
(7) 支持根据事件类型订阅 -
Otto
Square的开源项目,基于Guava的Android优化
项目地址:https://github.com/square/otto
文档介绍:http://square.github.io/otto/
EventBus与Otto的功能及性能对比文档
EventBus与Otto性能对比Demo Apk
-------------------------------------------------------------------------------------------------------------------------------------
Android中的EventBus
在这里先说说Android内置的两种跟EventBus类似的机制。Intent和BroadcastReceiver。
这两者都可以起到跟事件总线类似的效果。
注册广播接收器和单纯发一个intent就可以唤起其他组件,提醒其他组件更新,这是非常方便的,同时也是下面提到的两个开源方案所做不到的。
但这种机制也有不好地方,它们内部的实现都需要 IPC,虽然Android的Binder
使得IPC简单了点,
如果自己完全不需要IPC,下面说到的两个项目会更加适合。
otto
otto是square开源的一个基于Guava的EventBus的项目。跟Guava一样,otto使用Annotion作为事件的标记,@Subscribe
即事件的处理者,@Produce
是基本事件的生产者。举个官方给的例子:
@Subscribe public void answerAvailable(AnswerAvailableEvent event) {
// TODO: React to the event somehow!
}
@Produce public AnswerAvailableEvent produceAnswer() {
return new AnswerAvailableEvent(this.lastAnswer);
}
// 订阅者和发布者均需要向同一个总线注册
bus.register(this);
使用起来就是这么简单。订阅者向总线注册,如果此时存在一个生产者,那么这个生产者的方法会被调用以产生一个初始对象来初始化订阅者。另外,在总线接收到对应的事件之后,订阅者的方法就也会被调用。
bus.post(new AnswerAvailableEvent(100));
post事件并不需要对象向总线注册。post事件后,如果存在事件的订阅者那么订阅者的方法就会被调用。如果不存在订阅者,那么事件会被包裹成DeadEvent
重抛。(待做文章细说)。
默认情况下,otto只支持主线程的事件。比如下面代码所示,bus1和bus2是等价的。如果将策略设置为ANY,那么也可以在非主线程执行。只是不建议,这个库适合的场景也就只是在主线程而已,其他环境下会出现什么状况不做保证,有时会收不到消息!!
Bus bus1 = new Bus();
Bus bus2 = new Bus(ThreadEnforcer.MAIN);
// Bus bus3 = new Bus(ThreadEnforcer.ANY);
小问题
要想在基类中注册事件要花点心思。(不能通过this来向bus注册事件,因为在子类中的方法调用super到父类方法时,this指的永远是子类)。要想在基类注册事件,基本上只能写一个成员变量,在变量内部注册方法。逻辑会略奇怪。另外,可能需要自己实现一个BusProvider
一个简单的案例:
------------------------------------------------
2.GEventBus
greenrobot的另一个比较出名的开源项目(另外一个是greenDAO)。同样是EventBus,但这个项目不是基于Annotion的。因为Android的Runtime Annotion处理起来效率实在是不高,尤其是在4.0之前。在4.0之后也不见得效率有多大提高。
GEventBus使用的是字符串匹配,默认订阅者会调用带onEvent
或者说是EventBus类里面的DEFAULT_METHOD_NAME
作为前缀的方法。只有仔细跟踪代码之后,你才会发现它的几种线程模型是这么用的:
public void onEvent(SimpleEvent event) {};
public void onEventBackgroundThread(SimpleEvent event) {};
public void onEventMainThread(SimpleEvent event) {};
public void onEventAysnc(SimpleEvent event) {};
其他操作跟otto类似。只是GEventBus不支持生产者方法。(题外话:我是看了otto的demo之后才知道GEventBus的一般用法= =)
问题
- 跟otto一样,如果用继承可能会存在问题。但具体的问题大概恰好相反,如果一个父类向总线注册了事件,在otto里面是只有子类注册了事件,但在GEventBus中会是子类和父类都注册了。如果父类中注册了总线,那么子类中必须实现一个
onEvent*
方法,否则程序就会崩掉。解决方案,也算有吧,自己实现了一个蛮挫的暂时性解决方案 issus98
实际的使用可以参考这个,阿里巴巴开的而一个demo,他使用的就是OTTO。
https://github.com/liaohuqiu/android-cube-app
- 默认方法是只能带一个参数的,如果传入多个参数,那么GEventBus会完全忽略它,而且也不会报任何错误。这是个小细节,注意看文档的话大概也知道只能用一个参数,但是相较于otto会对参数不符合主动抛出一个
RuntimeException
,我始终觉得GEventBus有问题。