通过EventBus框架GET大牛的框架思维(1)

本文介绍了EventBus在Android中的使用,重点讲解了如何通过注册监听、发送事件和取消监听实现观察者模式,以及它在复杂场景下展示的解耦能力。
摘要由CSDN通过智能技术生成

}

});

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
  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值