我相信使用过EventBus的小伙伴应该都知道EventBus.getDefault().register()EventBus.getDefault().post()方法
接下来就是用代码去简单的实现一下EventBus通信的简单原理。
Subscrible注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// ElementType.METHOD 表示注解可以在方法上方使用
@Target(ElementType.METHOD)
// RetentionPolicy.RUNTIME 表示在程序运行阶段注解依然存在
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscrible {
ThreadMode threadMode() default ThreadMode.MAIN;
}
ThreadMode枚举
public enum ThreadMode {
// 主线程
MAIN,
// 子线程
BACKGROUND
}
EventBus类
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EventBus {
// 定义一个用来存储方法的键值对,键可以是一个Activity、Fragment等
// 一个Object对象可以对应很多方法
private Map<Object, List<SubscribleMethod>> cacheMap;
// 用来在子线程与主线程之间切换定义的
private Handler handler;
// 标准的单例模式需要定义的
private static volatile EventBus instance;
private EventBus(){
cacheMap = new HashMap<>();
handler = new Handler();
}
public static EventBus getDefault(){
if (instance == null) {
synchronized (EventBus.class){
if (instance == null){
instance = new EventBus();
}
}
}
return instance;
}
public void register(Object obj){
// 循环obj中所有的方法,讲带有Subscrible注解的方法全部存到cacheMap中
List<SubscribleMethod> list = cacheMap.get(obj);
if (list == null) {
list = findSubscribleMethods(obj);
cacheMap.put(obj,list);
}
}
private List<SubscribleMethod> findSubscribleMethods(Object obj) {
List<SubscribleMethod> list = new ArrayList<>();
Class<?> clazz = obj.getClass();
while (clazz != null) {
// 凡是系统级别的父类,直接省略
String name = clazz.getName();
if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
break;
}
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method method : declaredMethods) {
// 找到带有subscrible注解的方法
Subscrible subscrible = method.getAnnotation(Subscrible.class);
if (subscrible == null) {
continue;
}
// 判断subscribleMethod中的参数是否唯一
Class<?>[] types = method.getParameterTypes();
if (types.length != 1) {
Log.e("EventBus", "EventBus only accept one para");
}
ThreadMode threadMode = subscrible.threadMode();
SubscribleMethod subscribleMethod = new SubscribleMethod(method,threadMode,types[0]);
list.add(subscribleMethod);
}
clazz = clazz.getSuperclass();
}
return list;
}
// 获取想要调用的方法 进行回调;
public void post(Object type) {
// 直接循环cacheMao找到对应的方法:
Log.e("123","123");
Set<Object> set = cacheMap.keySet();
Iterator<Object> integer = set.iterator();
while (integer.hasNext()) {
Object obj = integer.next();
List<SubscribleMethod> list = cacheMap.get(obj);
for(SubscribleMethod subscribleMethod : list) {
if (subscribleMethod.getType().isAssignableFrom(type.getClass())) {
switch (subscribleMethod.getThreadMode()){
case MAIN:
// 主 主
// 子 主
if (Looper.myLooper() == Looper.getMainLooper()){
invoke(subscribleMethod,obj,type);
}else {
handler.post(new Runnable() {
@Override
public void run() {
invoke(subscribleMethod,obj,type);
}
});
}
break;
case BACKGROUND:
// 子 子
// 主 子
if (Looper.myLooper() != Looper.getMainLooper()) {
invoke(subscribleMethod,obj,type);
}else {
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.execute(new Runnable() {
@Override
public void run() {
invoke(subscribleMethod,obj,type);
}
});
}
}
}
}
}
}
private void invoke(SubscribleMethod subscribleMethod, Object obj, Object type) {
Method method = subscribleMethod.getMethod();
try {
method.invoke(obj,type);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
SubscribleMethod类(封装了方法、线程模式、回调方法的参数)
import java.lang.reflect.Method;
public class SubscribleMethod {
// 方法本身
private Method method;
// 线程模式
private ThreadMode threadMode;
// 回调方法中的参数
private Class<?> type;
public SubscribleMethod(Method method, ThreadMode threadMode, Class<?> type) {
this.method = method;
this.threadMode = threadMode;
this.type = type;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public ThreadMode getThreadMode() {
return threadMode;
}
public void setThreadMode(ThreadMode threadMode) {
this.threadMode = threadMode;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
}
参考视频:https://www.bilibili.com/video/BV1rT4y1E7hh