@TryLoveCatch
2022-06-07T07:20:19.000000Z
字数 4643
阅读 800
Android知识体系
定义事件->注册订阅->发布事件 ->处理事件
1、定义事件,其实就是一个普通的实体类
class EventTest {private String url,name;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}}
2、在Activity的onCreate和onDestroy里面分贝注册监听和反注册监听。
@Overrideprotected void onCreate(Bundle savedInstanceState) {......//注册监听EventBus.getDefault().register(this);}
@Overrideprotected void onDestroy() {super.onDestroy();//反注册EventBus.getDefault().unregister(this);}
3、在另一个Activity或者数据处理层里面 发布事件。
EventTest event = new EventTest();event.setName("111");event.setUrl("www.baidu.com");EventBus.getDefault().post(event);
4、在之前注册的Activity里面@Subscribe注解标记的方法,会被调用。
@Subscribe(threadMode = ThreadMode.POSTING, priority = 0, sticky = true)public void onEvent(EventTest event) {String name = event.getName();String url = event.getUrl();Log.e("点击",name+":"+url);};



private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {@Overrideprotected PostingThreadState initialValue() {return new PostingThreadState();}};/*** 线程的发送状态*/final static class PostingThreadState {final List<Object> eventQueue = new ArrayList<Object>(); //当前线程的事件队列boolean isPosting;boolean isMainThread;Subscription subscription;Object event;boolean canceled;}
/*** 根据 threadMode 发送事件给该订阅者* @param subscription* @param event* @param isMainThread*/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 { //入队,handler 发送消息到主线程,在主线程中反射调用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);}}

/*** 解除注册很简单,就从两个属性中移除当前类* @param subscriber*/public synchronized void unregister(Object subscriber) {List<Class<?>> 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());}}private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {//获取订阅这个事件的订阅者列表List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);if (subscriptions != null) {int size = subscriptions.size(); //只调用一次 subscriptions.size(),比在循环里每次都调用 subscriptions.size() 好for (int i = 0; i < size; i++) {Subscription subscription = subscriptions.get(i);if (subscription.subscriber == subscriber) { //将当前订阅者从订阅这个事件的订阅者列表中删除subscription.active = false;subscriptions.remove(i);i--;size--;}}}}
在编译时apt插件通过EventBusAnnotationProcessor分析注解,并利用注解标识的相关类的信息去生成相关的类。
Android 主流开源库源码分析(一)- EventBus 源码详解
Android 主流开源库源码分析(二)- EventBus 自己实现一个
Android面试之EventBus原理分析
Android事件总线(二)EventBus3.0源码解析
老司机教你 “飙” EventBus 3
Android 框架学习2:源码分析 EventBus 3.0 如何实现事件总线
