http://blog.csdn.net/lmj623565791/article/details/40794879
讲解的清晰
一共就使用EventBus的3个API
EventBus.getDefault().register(this);//订阅事件
EventBus.getDefault().post(object);//发布事件
EventBus.getDefault().unregister(this);//取消订阅
核心原理
EventBus.getDefault().register(this);
这行代码表示让EventBus扫描当前类, 把所有onEvent开头的方法记录下来,例如这样的方法名:
public class ItemListFragment extends ListFragment
{
public void onEventMainThread(ItemListEvent event) {
doSomething();
}
}
如何记录呢?在EventBus内部使用一个Map对象,其中Key为方法中参数的类型,Value的值包含了我们的方法名。
Map<Object, List<Class<?>>> typesBySubscriber;
value实际是一个List, 一个作为参数类型的key, 对应着一个List<方法名>的value, 这个List中每个item代表着一个方法名信息.
在上面这个例子中, ItemListEvent类型名字作为key,
ItemListFragment::onEventMainThread()方法名就被add到作为value的List<方法名>中.
EventBus.getDefault().register(mEventSubscriber);
private EventSubscriber mEventSubscriber = new EventSubscriber();
private class EventSubscriber {
public void onEventBackgroundThread(SaveSkinEvent event) {
onEventBackgroundThreadImpl(event);
}
}
则是让EventBus扫描mEventSubscriber这个对象, 把它这个类中以onEvent开头的方法记录下来.
当代码执行到
EventBus.getDefault().post(object);
EventBus就以object的类型作为key, 在它的Map中查到对应的List<方法名>,用反射的方式依次调用list中的所有方法.
EventBus的ThreadMode
EventBus包含4个ThreadMode:PostThread,MainThread,BackgroundThread,Async.
MainThread mode我们已经不陌生了, 这个模式用的最多.
具体的用法,极其简单,方法名为:
onEventPostThread, onEventMainThread,
onEventBackgroundThread,onEventAsync即可
具体什么区别呢?
onEventMainThread代表这个方法会在UI线程执行
onEventPostThread代表这个方法会在发布事件所在的线程中执行
BackgroundThread这个方法,如果在非UI线程发布的事件,则直接在发布事件所在的线程中去执行。如果在UI线程发布的事件,则加入到EventBus的一个后台任务队列,使用线程池一个接一个的调用执行。
Async代表这个方法被加入到后台任务队列,使用线程池调用.
项目实践
在browser代码里, BrowserEvents.java里定义了几十个内部类, 用于代表不同的事件,使用EventBus实现了各功能模块的解藕.
以字体更新为例,
ChromeTabbedActivity里定义一个BroadcastReceiver用以接受奇酷OS发出的字体改变事件.
private BroadcastReceiver mUpdateFontReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateFontSize();
}
};
private void updateFontSize() {
QEventBus.getEventBus().post(new BrowserEvents.updateNavViewFont());//发布事件
}
}
public class BrowserEvents {
public static class updateNavViewFont {
public updateNavViewFont() {
}
}
}
在NewsPageView, VideoPageView里都以BrowserEvents.updateNavViewFont作为参数类型的方法, 其方法名信息作为value值, 被添加到EventBus中的Map中.
public class NewsPageView {
public void onEventMainThreadImpl(BrowserEvents.updateNavViewFont event) {
updateNewsList();
}
}
当ChromeTabbedActivity发布BrowserEvents.updateNavViewFont事件后,
NewsPageView
和VideoPageView中的onEventMainThreadImpl(BrowserEvents.updateNavViewFont event)
依次被调用, 再通过调用updateNewsList();实现了在listView中的字体更新.
网友评论