使用
MainActiviity
public class MainActivity extends AppCompatActivity {
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 注册,思考为什么要注册?
EventBus.getDefault().register(this);
// 进入测试界面
mTv = (TextView) findViewById(R.id.test_tv);
mTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,TestActivity.class);
startActivity(intent);
}
});
}
/**
* threadMode 执行的线程方式
* priority 执行的优先级,值越大优先级越高
* sticky 粘性事件
*/
@Subscribe(threadMode = ThreadMode.MAIN,priority = 100,sticky = true)
public void test2(String msg){
// 如果有一个地方用 EventBus 发送一个 String 对象,那么这个方法就会被执行
Log.e("TAG","msg2 = "+msg);
mTv.setText(msg);
}
/**
* threadMode 执行的线程方式
* priority 执行的优先级
* sticky 粘性事件
*/
@Subscribe(threadMode = ThreadMode.MAIN,priority = 50,sticky = true)
public void test1(String msg){
// 如果有一个地方用 EventBus 发送一个 String 对象,那么这个方法就会被执行
Log.e("TAG","msg1 = "+msg);
mTv.setText(msg);
}
@Override
protected void onDestroy() {
// 解绑,思考为什么要解绑?
EventBus.getDefault().unregister(this);
super.onDestroy();
}
}
TestActivity
public class TestActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.test_tv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post("test_content");
}
});
}
}
源码分析
register源码分析
public void register(Object subscriber) {
// 首先获得class对象
Class> subscriberClass = subscriber.getClass();
// 通过 subscriberMethodFinder 来找到订阅者订阅了哪些事件.返回一个 SubscriberMethod 对象的 List, SubscriberMethod
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
// 订阅 A这个方法要看
subscribe(subscriber, subscriberMethod);
}
}
}
findSubscriberMethods源码分析
List findSubscriberMethods(Class> subscriberClass) {
//从缓存中获取,订阅者的class
List subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//支持编译时的注解方式,引入eventbus的apt
//ignoreGeneratedIndex属性表示是否忽略注解器生成的MyEventBusIndex
//ignoreGeneratedIndex默认值是false,可以通过EventBusBuilder设置它的值
if (ignoreGeneratedIndex) {
//利用反射获得订阅类中的方法
subscriberMethods = findUsingReflection(subscriberClass);
} else {
// 从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息
// 可以看Butterknifer的编译时注解
subscriberMethods = findUsingInfo(subscriberClass);
}
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass
+ " and its super classes have no public methods with the @Subscribe annotation");
} else {
METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods;
}
}
findUsingInfo源码分析
private List findUsingInfo(Class> subscriberClass) {
//使用到了享元设计模式,对对象进行了复用
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
//默认是个空
findState.subscriberInfo = getSubscriberInfo(findState);
if (findState.subscriberInfo != null) {
SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
for (SubscriberMethod subscriberMethod : array) {
if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
findState.subscriberMethods.add(subscriberMethod);
}
}
} else {
//所以会进入到这儿,通过反射去找
findUsingReflectionInSingleClass(findState);
}
findState.moveToSuperclass();
}
// 释放 findState 享元模式
return getMethodsAndRelease(findState);
}
findUsingReflectionInSingleClass源码分析
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// 通过反射来获取订阅类的所有方法
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
// for 循环所有方法
for (Method method : methods) {
// 获取方法访问修饰符
int modifiers = method.getModifiers();
// 找到所有声明为 public 的方法
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class>[] parameterTypes = method.getParameterTypes();// 获取参数的的 Class,比如案例中String
if (parameterTypes.length == 1) {// 只允许包含一个参数
//获得注解
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
// 获取事件的 Class ,也就是方法参数的 Class
Class> eventType = parameterTypes[0];
// 检测添加
if (findState.checkAdd(method, eventType)) {
// 获取 ThreadMode
ThreadMode threadMode = subscribeAnnotation.threadMode();
// 往集合里面添加 SubscriberMethod ,解析方法注解所有的属性
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
}
第一步:去解析注册者对象的所有方法,并且找出带有注解 Subscribe 注解的的方法,
然后通过Annotation解析所有细节参数(threadMode,priority,sticky,eventType,method),
把这些参数封装成一个 SubscriberMethod,添加到集合返回。
A: subscribe(subscriber, subscriberMethod);源码分析
//第一个参数是订阅者,这里是MainActivitiy,subscriberMethod这里是封装好的方法的集合
subscribe(subscriber, subscriberMethod);
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
// 获取方法参数的 class,String.class
Class> eventType = subscriberMethod.eventType;
// 创建一个 Subscription
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
// 获取订阅了此事件类的所有订阅者信息列表
// private final Map, CopyOnWriteArrayList> subscriptionsByEventType;
//key是enevtType
// value 存放的是 Subscription 的集合列表
// Subscription 包含两个属性,一个是 subscriber 订阅者(反射执行对象),一个是 SubscriberMethod 注解方法的所有属性参数值
CopyOnWriteArrayList subscriptions = subscriptionsByEventType.get(eventType);//默认是空
if (subscriptions == null) {
// 线程安全的 ArrayList
subscriptions = new CopyOnWriteArrayList<>();
// 添加
subscriptionsByEventType.put(eventType, subscriptions);
} else {
// 是否包含,如果包含再次添加抛异常
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
// 处理优先级
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
//按照优先级进行排序
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
// 通过 subscriber 获取 List>
//private final Map
post源码分析
public void post(Object event) {
// currentPostingThreadState 是一个 ThreadLocal,
// 他的特点是获取当前线程一份独有的变量数据,不受其他线程影响。
PostingThreadState postingState = currentPostingThreadState.get();
// postingState 就是获取到的线程独有的变量数据
List
postSingleEvent源码分析
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
//event text ,
Class> eventClass = event.getClass();
boolean subscriptionFound = false;
if (eventInheritance) {
List> eventTypes = lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
for (int h = 0; h < countTypes; h++) {
Class> clazz = eventTypes.get(h);
subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
}
} else {
//看这个源码
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
}
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class> eventClass) {
//event text eventClass:String.class
CopyOnWriteArrayList subscriptions;
synchronized (this) {
//根据string.class得到Subscription 列表
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
//遍历所有的集合
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
//发送事件
postToSubscription(subscription, event, postingState.isMainThread);
//是否取消
aborted = postingState.canceled;
} finally {
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
}
if (aborted) {
break;
}
}
return true;
}
return false;
}
postToSubscription源码分析
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
// 根据不同的线程模式执行对应
switch (subscription.subscriberMethod.threadMode) {
// 同一个线程,在哪个线程发送事件,那么该方法就在哪个线程执行
case POSTING:
invokeSubscriber(subscription, event);
break;
// 主线程
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
//否则切换到主线程执行
mainThreadPoster.enqueue(subscription, event);
}
break;
// 子线程:如果发布事件的线程是主线程,那么调用线程池中的子线程来执行订阅方法;否则直接执行
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
// 异步线程:无论发布事件执行在主线程还是子线程,都利用一个异步线程来执行订阅方法
case ASYNC:
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
第三步post()
遍历 subscriptionsByEventType,找到符合的方法调用方法的 method.invoke() 执行。
unregister源码分析
public synchronized void unregister(Object subscriber) {
// 获取订阅对象的所有订阅事件类列表
List> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class> eventType : subscribedTypes) {
// 将订阅者的订阅信息移除
unsubscribeByEventType(subscriber, eventType);
}
// 将订阅者从列表中移除
typesBySubscriber.remove(subscriber);
} else {
Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
unsubscribeByEventType源码分析
private void unsubscribeByEventType(Object subscriber, Class> eventType) {
// 获取事件类的所有订阅信息列表,将订阅信息从订阅信息集合中移除,同时将订阅信息中的active属性置为FALSE
List subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
if (subscription.subscriber == subscriber) {
// 将订阅信息激活状态置为FALSE
subscription.active = false;
// 将订阅信息从集合中移除
subscriptions.remove(i);
i--;
size--;
}
}
}
}