}
});
EventBus.getDefault().register(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReturn(Message message) {
mTextView.setText(message.mContent);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
来源Activity
:
public class SecondActivity extends AppCompatActivity { TextView mTextView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = findViewById(R.id.tv_demo); mTextView.setText("SecondActivity,点击返回"); mTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Message message = new Message(); message.mContent = "从SecondActivity返回"; EventBus.getDefault().post(message); finish(); } }); } } 效果如下: ![image](https://img-blog.csdnimg.cn/img_convert/afd71645bad1fdf3aecfdfc0a527a1de.webp?x-oss-process=image/format,png) 似乎只是换了一种写法,但在场景愈加复杂后,`EventBus`能够体现出更好的解耦能力 **背景知识** 主要涉及三方面的知识: 1. 观察者模式(or 发布-订阅模式) 2. Android消息机制 3. Java并发编程 **实现过程** EventBus`的使用分三个步骤:注册监听、发送事件和取消监听,相应本文也将分这三步来实现。 **注册监听** 定义一个注解: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Subscribe { ThreadMode threadMode() default ThreadMode.POST; } greenrobot/EventBus`还支持优先级和粘性事件,这里只支持最基本的能力:区分线程,因为如更新UI的操作必须放在主线程。`ThreadMode`如下: public enum ThreadMode { MAIN, // 主线程 POST, // 发送消息的线程 ASYNC // 新开一个线程发送 } 在对象初始化的时候,使用`register`方法注册,该方法会解析被注册对象的所有方法,并解析声明了注解的方法(即观察者),核心代码如下: public class EventBus { ... public void register(Object subscriber) { if (subscriber == null) { return; } synchronized (this) { subscribe(subscriber); } } ... private void subscribe(Object subscriber) { if (subscriber == null) { return; } // TODO 巨踏马难看的缩进 Class<?> clazz = subscriber.getClass(); while (clazz != null && !isSystemClass(clazz.getName())) { final Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { Subscribe annotation = method.getAnnotation(Subscribe.class); if (annotation != null) { Class<?>[] paramClassArray = method.getParameterTypes(); if (paramClassArray != null && paramClassArray.length == 1) { Class<?> paramType = convertType(paramClassArray[0]); EventType eventType = new EventType(paramType); SubscriberMethod subscriberMethod = new SubscriberMethod(method, annotation.threadMode(), paramType); realSubscribe(subscriber, subscriberMethod, eventType); } } } clazz = clazz.getSuperclass(); } } ... private void realSubscribe(Object subscriber, SubscriberMethod method, EventType eventType) { CopyOnWriteArrayList subscriptions = mSubscriptionsByEventtype.get(subscriber); if (subscriptions == null) { subscriptions = new CopyOnWriteArrayList<>(); } Subscription subscription = new Subscription(subscriber, method); if (subscriptions.contains(subscription)) { return; } subscriptions.add(subscription); mSubscriptionsByEventtype.put(eventType, subscriptions); } ... } 执行过这些逻辑后,该对象所有的观察者方法都会被存在一个Map中,其Key是`EventType`,即观察事件的类型,Value是订阅了该类型事件的所有方法(即观察者)的一个列表,每个方法和对象一起封装成了一个`Subscription`类: public class Subscription { public final Reference subscriber; public final SubscriberMethod subscriberMethod; public Subscription(Object subscriber, SubscriberMethod subscriberMethod) { this.subscriber = new WeakReference<>(subscriber);// EventBus3 没用弱引用? this.subscriberMethod = subscriberMethod; } @Override public int hashCode() { return subscriber.hashCode() + subscriberMethod.methodString.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof Subscription) { Subscription other = (Subscription) obj; return subscriber == other.subscribe && subscriberMethod.equals(other.subscriberMethod); } else { return false; } } } 如此,便是注册监听方法的核心逻辑了。 **消息发送** 消息的发送代码很简单: public class EventBus { ... private EventDispatcher mEventDispatcher = new EventDispatcher(); private ThreadLocal