What I know from EventBus
2015-12-28 22:09
211 查看
Why we use Event Bus
In the previously android app, we often use
intent or handler to deliver the message between android’s components, that will make the code a little complex and impact the app’s performance
when deliver large object.
Now there may be a better way by using Event Bus. Event Bus can decouples the senders and receivers which are usually different components, also make your code simpler.
So what are the most popular libraries about Event Bus using in android?
Guava(番石榴)
Obviously, Guava is not the fruit at here.
The Guava project contains several of Google's core libraries that we rely on in our Java-based projects: collections, caching,
primitives support, concurrency libraries, common annotations, string processing, I/O, and
EventBus. Each of these tools really do get used every day by Googlers, in production services.
Guava(Chinese):
http://ifeve.com/google-guava/
Github: https://github.com/google/guava
Otto
Otto is an event bus designed to decouple different parts of your application while still allowing them to communicate efficiently. Forked from Guava, Otto adds unique functionality refined
event bus as well as specialising it to the Android platform.
Github: https://github.com/square/otto
EventBus
Today I will analysing the source code of EventBus.
Github: https://github.com/greenrobot/EventBus
EventBus Introduction
EventBus is publish/subscribe event bus optimized for Android.
simplifies the communication between components
decouples(解耦) event senders and receivers
performs well with Activities, Fragments, and background threads
avoids complex and error-prone(易于出错) dependencies and life cycle issues
makes your code simpler
is fast
is tiny (<50k jar)
is proven in practice by apps with 100,000,000+ installs
has advanced features like delivery threads, subscriber priorities, etc.
How to use EventBus
EventBus in 3 steps
Define events:
public class MessageEvent { /* Additional fields if needed */ }
Prepare subscribers:
eventBus.register(this);
public void onEvent(AnyEventType event) {/* Do something */};
Post events:
eventBus.post(event);
ThreadMode
onEvent(EventType event)
PostThread is
default ThreadMode.
Subscriber will be called in the same thread which is posting the event.
onEventMainThread(EventType event)
Subscriber will be called in the main thread.
If the posting thread is main thread, onEventMainThread(EventType) will be called directly; If not, the Event will be sent to main thread by the handler, then call the onEventMainThread(EventType) in handleMesage(Message).
onEventMainThread(EventType) must return quickly to avoid blocking the main thread.
onEventBackgroundThread(EventType event)
Subscriber will be called in a background thread.
onEventBackgroundThread(EventType) will be called directly if posting thread is not main thread. If posting thread is the main thread, EventBus uses a single background thread, that will deliver
all its events sequentially.
onEventBackgroundThread(EventType) must return quickly to avoid blocking the background thread.
onEventAsync(EventType)
Subscriber will be called in a separate thread.
This is not relative to the posting thread or the main thread.
Event handler methods should use this mode if their execution might take some time(network request).
EventBus EasyDemo
Subscriber:
Post:
Detail: https://github.com/Visualrainy/EventBusDemo
Source Code
In most cases, we register subscriber to EventBus in
onCreate method and unregister in onDestory method.
Maybe there has a question came from you what EventBus do in register.
EventBus.getDefault().register(this);
Firstly,
EventBus.getDefault() is singleInstance.
Here using the double check defaultInstance is null or not to avoid concurrency(并发).
Secondly, there have serval register methods in EventBus, but call
register(Object subscriber, boolean sticky, int priority) finally.
There have 3 parameters in register method.
subscriber: usually a class which we use “this” in register(this).
sticky and priority will be analysed later.
Thirdly, in the register method will call
findSubscribeMehtods(Class<?> subscriberClass)
Just analysing serval key points in this method.
line 57~59: Whether the subscriber class has been scanned before.
line 75: Get the subscriber’s methods.
line 78~82: Whether the method start with “onEvent”, the method’s modifier is public, the method has one parameter.
line 85~93: Get the method’s thread mode by method’s suffix(后缀).
line 107: Construct a new SubscribeMethodClass() by passing the method, threadMode and eventType(parameter class Type)
line 116: Scan subscriber’s super class.
Fourthly, there has a subscribe(Object subscriber, SubscriberMethod subscriberMethod, boolean sticky, int priority) method
in register
There have 4 key points in this method.
line 174~177: subscriptionsByEventType: is a type of map<string, list<subscription>>, this variable records each evenType’s subscriptions(记录eventType的都有哪些subscription(subscriber,
subscriberMethod,priority),key就是eventType).
line 187~193: Insert the subscription in subscriptions according to the priority.
line 195~200: typesBySubscriber: is a type of map<subscriber, list<eventType>>, this variable records each subscriber’s eventTypes(记录subscriber都有哪些eventType,
key就是subscriber)
line 202~212: If sticky is true and stickyEvent is not null, post the stickyEvent immediately.
EventBus.getDefault().post(title);
Firstly, add the event to the eventQueue, when the eventQueue is not empty, EventBus will call postSingleEvent(Object event, PostingThreadState postingState)
Secondly, the eventInheritance default is true, there will call postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass)
There also a key point in this methods.
line 401~403: Find the subscription by the event class type.
Thirdly, if subscription is not empty, it will call postToSubscription(Subscription subscription, Object event, boolean isMainThread)
In this method, it will be call invokeSubscriber or enqueue the event to the poster according to isMainThread and thread mode.
At last, it will call
invokeSubscriber(Subscription subscription, Object event).
In this method, we can see it invoke the event handle method by reflection.
What can we learn?
The code use some technology to avoid concurrency, like double check in single instance, CopyOnWriteArrayList, synchronized.
Reuse the PendingPost in pendingPostPool.
How to use ExecutorService to schedule the thread and avoid concurrency.
Learn Source Code also help us understand the origin of the library.
//unuse things below:
eventTypesFound:hashSet<String>: methodName>parameterTypesClassName
eventType:parameterTypesClassName
SubscriberMethod:method, threadMode, eventType
methodCache:<subscriberClass’s name, List<SubscriberMethod>>
subscriptionsByEventType:map<string, list<subscription>>记录eventType的都有哪些subscription(subscriber, subscriberMethod,priority),key就是eventType
typesBySubscriber:map<subscriber, list<eventType>>
分析更个类的大体作用和功能,了解某些地方的使用巧妙之处
SourceCode:
相关文章推荐
- poj 2492 A Bug's Life
- 二叉树的镜像
- javaMail学习一,基本概念
- JQuery EasyUI 发送两次请求
- ,
- 文章标题
- 数据挖掘中如何处理缺失数据
- c#访问级别约束的问题
- 如何带领一个团队
- 【splay】BZOJ 1014: [JSOI2008]火星人prefix
- Quickstart containers
- java中getBytes()用法
- MySql查看与修改auto_increment方法
- jQuery 判断是否包含某个属性
- mysql jdbc驱动源码分析(获取Statement对象)
- 以数据为核心的SOC3.0时代到来
- 以数据为核心的SOC3.0时代到来
- C++ 函数内部定义函数原型?
- hadoop源码学习 InputFormat抽象类
- Git 钩子