在上一篇文章我讲了EventBus源码,现在我们来手写一下EventBus
使用
MainActiviity
public class MainActivity extends AppCompatActivity {
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 注册,思考为什么要注册?
EventBus.getDefault().register(this);
// 进入测试界面
mTv = (TextView) findViewById(R.id.test_tv);
mTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,TestActivity.class);
startActivity(intent);
}
});
}
/**
* threadMode 执行的线程方式
* priority 执行的优先级,值越大优先级越高
* sticky 粘性事件
*/
@Subscribe(threadMode = ThreadMode.MAIN,priority = 100,sticky = true)
public void test2(String msg){
// 如果有一个地方用 EventBus 发送一个 String 对象,那么这个方法就会被执行
Log.e("TAG","msg2 = "+msg);
mTv.setText(msg);
}
/**
* threadMode 执行的线程方式
* priority 执行的优先级
* sticky 粘性事件
*/
@Subscribe(threadMode = ThreadMode.MAIN,priority = 50,sticky = true)
public void test1(String msg){
// 如果有一个地方用 EventBus 发送一个 String 对象,那么这个方法就会被执行
Log.e("TAG","msg1 = "+msg);
mTv.setText(msg);
}
@Override
protected void onDestroy() {
// 解绑,思考为什么要解绑?
EventBus.getDefault().unregister(this);
super.onDestroy();
}
}
TestActivity
public class TestActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.test_tv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post("test_content");
}
});
}
}
首先拷贝一些用到的类Subscribe注解,SubscriberMethod,Subscription,ThreadMode,这些源码中都有就不拷贝了
开始手写EventBus
public class EventBus {
private static volatile EventBus defaultInstance;
// subscriptionsByEventType 这个集合存放的是?
// key 是 Event 参数的类
// value 存放的是 Subscription 的集合列表
// Subscription 包含两个属性,一个是 subscriber 订阅者(反射执行对象),一个是 SubscriberMethod 注解方法的所有属性参数值
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
// typesBySubscriber 这个集合存放的是?
// key 是所有的订阅者
// value 是所有订阅者里面方法的参数的class
private final Map<Object, List<Class<?>>> typesBySubscriber;
private EventBus() {
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
}
//单例设计模式
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
/**
* 注册
*/
public void register(Object object) {
//1.解析所有的方法封装成SubscibeMethod集合
Class<?> objectClass = object.getClass();
List<SubscriberMethod> subscriberMethods = new ArrayList<>();
//1.2.获得所有方法
Method[] methods = objectClass.getDeclaredMethods();
for (Method method : methods) {
//1.3.获得所有被Subscribe所修饰的注解的方法
Subscribe subscribe = method.getAnnotation(Subscribe.class);
if (subscribe != null) {
//获得注解参数的类
Class<?>[] parameterTypes = method.getParameterTypes();
Class<?> eventType = parameterTypes[0];
SubscriberMethod subscriberMethod = new SubscriberMethod(method
, eventType, subscribe.threadMode(), subscribe.priority(), subscribe.sticky());
subscriberMethods.add(subscriberMethod);
}
}
//2.按照一定顺序存放到 subscriptionsByEventType 里面去
for (SubscriberMethod method : subscriberMethods) {
subscriber(object, method);
}
}
//2.按照一定顺序存放到 subscriptionsByEventType 里面去
private void subscriber(Object object, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;
//默认是空
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
}
//添加到subscriptionsByEventType
Subscription subscription = new Subscription(object, subscriberMethod);
subscriptions.add(subscription);
//3.添加到typesBySubscriber,用来移除的
List<Class<?>> subscribedEvents = typesBySubscriber.get(object);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(object, subscribedEvents);
}
if (!subscribedEvents.contains(eventType)) {
subscribedEvents.add(eventType);
}
}
/**
* 解注册
*/
public void unregister(Object object) {
List<Class<?>> eventTypes = typesBySubscriber.get(object);
if (eventTypes != null) {
for (Class<?> eventType : eventTypes) {//String.class
removeObject(eventType, object);
}
}
}
private void removeObject(Class<?> eventType, Object object) {
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
if (subscription.subscriber == object) {
// 将订阅信息从集合中移除
subscriptions.remove(i);
i--;
size--;
}
}
}
}
//发送
public void post(Object event) {
// 遍历 subscriptionsByEventType,找到符合的方法调用方法的 method.invoke() 执行。要注意线程切换
Class<?> eventType = event.getClass();
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
for (Subscription subscription : subscriptions) {
executeMethod(subscription, event);
}
}
}
private void executeMethod(final Subscription subscription, final Object event) {
ThreadMode threadMode = subscription.subscriberMethod.threadMode;
boolean isMainThread = Looper.getMainLooper() == Looper.myLooper();
switch (threadMode) {
case POSTING:
invokeMethod(subscription, event);
break;
case MAIN:
if (isMainThread) {
invokeMethod(subscription, event);
} else {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
invokeMethod(subscription, event);
}
});
}
break;
case BACKGROUND:
if (!isMainThread) {
invokeMethod(subscription, event);
} else {//自己开一个子线程去更新
AsyncPoster.enqueue(subscription, event);
}
break;
case ASYNC:
AsyncPoster.enqueue(subscription, event);
break;
}
}
private void invokeMethod(Subscription subscription, Object event) {
try {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} catch (Exception e) {
e.printStackTrace();
}
}
}
AsyncPoster:线程池执行异步任务
public class AsyncPoster implements Runnable {
Subscription subscription;
Object event;
//线程池
private final static ExecutorService executorService = Executors.newCachedThreadPool();
public AsyncPoster(Subscription subscription, Object event) {
this.subscription = subscription;
this.event = event;
}
/**
* 执行异步
*/
public static void enqueue(Subscription subscription, Object event) {
AsyncPoster asyncPoster = new AsyncPoster(subscription, event);
executorService.execute(asyncPoster);
}
@Override
public void run() {
try {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} catch (Exception e) {
e.printStackTrace();
}
}
}