###EventBus简单使用
EventBus简单介绍
- 1.Androd 事件发布/订阅框架
- 2.事件传递即可适用于Android四大组件间通讯
- 3.EventBus的有点是代码简洁,使用简单,并将事件发布和订阅充分讲解
Handler的使用
private Handler handler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bt).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message=handler.obtainMessage();
message.arg1=1;
message.obj="消息信息";
handler.sendMessage(message);
System.out.println(Thread.currentThread().getName());
}
});
new MyThread().start();
}
// java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
private class MyThread extends Thread{
@Override
public void run() {
Looper.prepare();
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println(Thread.currentThread().getName());
System.out.println("msg.what=="+msg.what+"wsg.obj=="+msg.obj);
}
};
Looper.loop();
}
}
EventBus流程图
github官网:https://github.com/greenrobot/EventBus
依赖:compile 'org.greenrobot:eventbus:3.1.1’
eventBus的用法
public class Test extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bt).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MyBusEvent("我是EventBus"));
}
});
}
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode= ThreadMode.MAIN)
public void onMessageEvent(MyBusEvent event){
Toast.makeText(this,event.message,Toast.LENGTH_SHORT).show();
}
}
1.定义事件event
2.准备订阅者
3.订阅者同时需要在总线上注册和注销自己
4.发送事件
###源码分析
1.EventBus.getDefault()源码分析
//同步锁单例模式
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
//构造函数
public EventBus() {
this(DEFAULT_BUILDER);
}
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
EventBus(EventBusBuilder builder) {
//event为key,以Subscription为value.找到我们对应的订阅者
subscriptionsByEventType = new HashMap<>();
//以Subscriber为key,以types为value,反注册和注册
typesBySubscriber = new HashMap<>();
//粘性事件,当我们发送event,再注册粘性事件,这个粘性会收到之前的事件
stickyEvents = new ConcurrentHashMap<>();
//poster就是负责线程间调度
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
//后台运行,取出所有然后事件分发
backgroundPoster = new BackgroundPoster(this);
//取出一个,然后事件分发
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
//找到设置好的注解
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
//是否异常信息打印
logSubscriberExceptions = builder.logSubscriberExceptions;
//没有订阅者,是否打印
logNoSubscriberMessages = builder.logNoSubscriberMessages;
//调用事件处理时,出现异常是否打印
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
//没有事件处理
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
//是否都需要发送
eventInheritance = builder.eventInheritance;
//线程池
executorService = builder.executorService;
}
HandlerPoster源码分析
HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
super(looper);
this.eventBus = eventBus;
//poster在handler.message中存在最大的时间值
this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
queue = new PendingPostQueue();
}
public void handleMessage(Message msg) {
boolean rescheduled = false;
try {
long started = SystemClock.uptimeMillis();
while (true) {
//PendingPost 只有两个方法obtainPendingPost获得PendingPost和releasePendingPost释放
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
pendingPost = queue.poll();
if (pendingPost == null) {
//handlerActive 代表是否运行成功
handlerActive = false;
return;
}
}
}
//分发事件
eventBus.invokeSubscriber(pendingPost);
long timeInMethod = SystemClock.uptimeMillis() - started;
if (timeInMethod >= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
rescheduled = true;
return;
}
}
} finally {
handlerActive = rescheduled;
}
2.Subscribe源码分析
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
//线程模式
ThreadMode threadMode() default ThreadMode.POSTING;
//是否为粘性事件 粘性事件:事件消费者在事件发布之后才注册的也能接受到改事件的特殊性,如粘性广播,在广播接受后会保存刚刚发送的广播
boolean sticky() default false;
//优先级
int priority() default 0;
}
ThreadMode源码分析
public enum ThreadMode {
//订阅者将在同一个线程中调用,该线程正在发布事件。这是默认的。事件交付意味着最少的开销,因为它避免了完全的线程切换。因此,对于已知的完成的简单任务来说,这是一个非常短的时间,而不需要主线程。使用此模式的事件处理程序必须快速返回,以避免阻塞发布线程,这可能是主线程。
POSTING,
//用户将在Android的主线程(有时被称为UI线程)调用。如果发布线程是主线程,则将直接调用事件处理程序方法。使用此模式的事件处理程序必须快速返回以避免阻塞主线程
MAIN,
//用户将在后台线程中调用。如果发布线程不是主线程,事件处理程序方法将直接在发布线程中调用。如果发布线程是主线程,EventBus使用一个单独的后台线程,它将按顺序交付所有事件。使用此模式的事件处理程序应该尝试快速返回,以避免阻塞后台线程。
BACKGROUND,
//事件处理程序方法应该使用这种模式,如果它们的执行可能需要一些时间,例如网络访问。避免在同一时间触发大量的异步处理程序方法来限制并发线程的数量。EventBus使用线程池有效地重用已完成的异步事件处理程序通知中的线程。
ASYNC
}
3.register源码分析
public void register(Object subscriber) {
//获得反射类
Class<?> subscriberClass = subscriber.getClass();
//找到订阅者方法所有集合
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
subscriberMethodFinder.findSubscriberMethods(subscriberClass)源码分析
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//判断是否有缓存,有缓存直接返回
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//默认是false
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
//获得订阅方法集合
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<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
//获取FindState 对象
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();
}
//方法释放
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 (Method method : methods) {
//获得方法的修饰符
int modifiers = method.getModifiers();
//判断是否是public和是否可以忽略
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
//获得方法的参数
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
//获得@Subscribe注解的
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
//获得线程模式
ThreadMode threadMode = subscribeAnnotation.threadMode();
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
}
prepareFindState源码分析
private FindState prepareFindState() {
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
//for循环
FindState state = FIND_STATE_POOL[i];
if (state != null) {
FIND_STATE_POOL[i] = null;
return state;
}
}
}
//如果为空则直接new
return new FindState();
}
subscribe(subscriber, subscriberMethod);源码分析
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;
//封装了订阅者
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//可读写
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
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;
}
}
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
//是否是粘性事件
if (subscriberMethod.sticky) {
if (eventInheritance) {
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
//判断是否有继承关系
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
//分发事件
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
>首先判断是否有注册过改事件
然后按照优先级加入到suscriptionsByEventType的value的List中
然后添加到typesBySubscriber的value中的List中
分发事件 checkPostStickyEventToSubscription
checkPostStickyEventToSubsrciption源码分析
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
//如果粘性事件不为空
if (stickyEvent != null) {
//Looper.getMainLooper() == Looper.myLooper()判断是主线程
postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
}
}
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);
}
}
4.post源码解析
public void post(Object event) {
//线程独有的
PostingThreadState postingState = currentPostingThreadState.get();
//事件队列
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
//判断是否正在发送
if (!postingState.isPosting) {
//判断是主线程
postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
//状态清零
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}