前言
在system ui的recents中有大量使用到EventBus的地方,这里会揭示EventBus到底是什么,以及EventBus是如何运作的。
从一个朴素的角度来说,EventBus其实是一个Subscriber-Event的机制,对于Sbuscriber来说,它们的回调函数会在适当的时候被Event所激活。
Start of System UI
system UI的启动flow图:
整个System UI的启动中,我们需要关注的点在:EventBus: register(sSystemServicesProxy, EVENT_BUS_PRIORITY);
Register EventBus
直接看EventBus的代码:
|
|
对于EventBus而言,它是一个单例存在于SystemUI的进程中,通过getDefault
方法给出具体的EventBus实例,而通过register方法把对应的suscriber注册到内部。
EventBus还实现了一套进程间的suscriber机制
registerSubscriber
简单看一下register函数的实体:
|
|
其中有一句比较敏感的语句:Method[] methods = subscriberType.getDeclaredMethods();
了解过java反射的话,就可以理解这一句代码了,这边是通过class对象拿到对应的methods。
而后,是通过一个for循环去遍历这些methods,并且挨个去isValidEventBusHandlerMethod
isValidEventBusHandlerMethod
这个函数的目的是筛选出当前的subscriber中的函数是否满足EventBus的callback函数签名。
对于EventBus的函数签名,参考EventBus.java
|
|
因此可以看到,Subscriber的callback函数名都是onBusEvent
(进程内),或者onInterprocessBusEvent
(进程间)。
有了这样的基础知识,我们再来看看isValidEventBusHandlerMethod
|
|
所以对于一个Method是否valid,我们有如下几个判定:
Modifier.isPublic(modifiers)
:函数是publicModifier.isFinal(modifiers)
:函数必须是finalmethod.getReturnType().equals(Void.TYPE)
:函数返回值为voidparameterTypes.length == 1
:函数的参数数量是1
当通过了这四重考验之后,我们再去检查它的入参类型,以及函数名称:
对于进程间的Subscriber:
EventBus.InterprocessEvent.class.isAssignableFrom(parameterTypes[0])
method.getName().startsWith(INTERPROCESS_METHOD_PREFIX))
对于进程内的Subscriber:
EventBus.Event.class.isAssignableFrom(parameterTypes[0])
method.getName().startsWith(METHOD_PREFIX)
这两步的检查,归结一下其实就是检查入参的类型和函数的名称
Add to list
我们假定Suscriber中的onBusEvent已经顺利通过考验,所以我们就来到:
|
|
因此,在mEventTypeMap
中维护了一张从class到EventHandler的表
|
|
其中的key,也即Class<? extends Event>
,其实是对应的一个一个具体Event。
而value,就是
|
|
这之中:
Subscriber sub = new Subscriber(subscriber, SystemClock.uptimeMillis());
EventHandlerMethod method = new EventHandlerMethod(m, eventType);
m:Method m
Class<? extends Event> eventType = (Class<? extends Event>) parameterTypes[0];
priority
: register的入参
所以,EventHandler handler
,它知道谁是subscriber(sub);知道对应的的method以及它的入参(method);了解注册者的优先级(priority)。因此,它可以很轻松地完成transform event。
最后:sortEventHandlersByPriority
对EventHandler的list做一次排序
Send EventBus
上面的整个flow已经完成了Event的注册,下面我们来讲述一下event来了之后是如何被送到Subscriber。
EventBus.send
|
|
首先是thread condition检查,只有main thread才有机会send。
然后是一个function by pass
queueEvent
|
|
先通过event type获取到对应的EventHandler list,刚才我们也知道,其实一个EventHandler其实是一个Subscriber。由于之前已经做过了排序,所以这边的list其实是按照优先级高低依次排序了的。
processEvent
|
|
其实也就是通过sub实例以及event,做了一下method invok,所以就会跑到之前Subscriber的onBusEvent中去了。
小结
其实整个EventBus的实现有很多巧妙的地方。
这里充分利用了函数签名和函数名称的一致性,建立了一套EventBus的Subscriber框架。实现了代码级别的功能解耦,使得同一个事件可以被不同的Subscriber对象所处理,对于Subscriber而言,只需要关注自己关心的那一块即可。