简单的手写EventBus通信
我相信使用过EventBus的小伙伴应该都知道EventBus.getDefault().register()EventBus.getDefault().post()方法
接下来就是用代码去简单的实现一下EventBus通信的简单原理。
- EvnentBus是通过解耦发布者和订阅者简化Android事件传递。
- 简单理解EventBus原理的话就是他利用了一个第三方去管理方法,用到的时候就去那个第三方拿那个与参数类型对应的方法。
- EventBus在使用post方法时是通过用参数类型的方式去匹配得到对应的方法来执行的。
Subscrible注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@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 {
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){
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 = method.getAnnotation(Subscrible.class);
if (subscrible == null) {
continue;
}
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) {
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
|