赞
踩
我相信使用过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; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。