What I know from EventBus

Why we use Event Bus
     In the previously android app, we often use intent or handler to deliver the message between androids 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/  

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.

EventBus
Today I will analysing the source code of 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:
     
    

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:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值