@TryLoveCatch
2022-06-07T15:20:19.000000Z
字数 4643
阅读 528
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里面分贝注册监听和反注册监听。
@Override
protected void onCreate(Bundle savedInstanceState) {
...
...
//注册监听
EventBus.getDefault().register(this);
}
@Override
protected 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>() {
@Override
protected 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 如何实现事件总线