您的位置:首页 > 其它

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:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: