理解了EventBus的源码之后,接下来就仿照实现一个自己的EventBus
一、创建一个TestThreadMode
public enum TestThreadMode {
MAIN,
BACKGROUND
}
二、创建一个TestSubscribe注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestSubscribe {
// 默认TestThreadMode.MAIN;
TestThreadMode threadMode() default TestThreadMode.MAIN;
boolean stick() default false;
}
三、SubscribeMethod类封装注解方法等
public class SubscribeMethod {
private Method method;
private TestThreadMode threadMode;
private Class<?> type;
private boolean stick;
public SubscribeMethod(Method method, TestThreadMode threadMode, Class<?> type,boolean stick) {
this.method = method;
this.threadMode = threadMode;
this.type = type;
this.stick = stick;
}
public boolean isStick() {
return stick;
}
public void setStick(boolean stick) {
this.stick = stick;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public TestThreadMode getThreadMode() {
return threadMode;
}
public void setThreadMode(TestThreadMode threadMode) {
this.threadMode = threadMode;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
}
创建TestEventBus
public class TestEventBus {
private static volatile TestEventBus testEventBus;
//保存SubscribeMethod的map集合,是以事件类型为key
private Map<Object,List<SubscribeMethod>> cacheMap;
//保存粘性事件
private Map<Class<?>,Object> stickMap;
private Handler mHandler;
private TestEventBus(){
cacheMap = new HashMap<>();
mHandler = new Handler();
stickMap = new HashMap<>();
}
//仿EventBus使用单例
public static TestEventBus getDefault() {
if(testEventBus == null){
synchronized (TestEventBus.class){
if(testEventBus == null){
testEventBus = new TestEventBus();
}
}
}
return testEventBus;
}
//注册
@TargetApi(Build.VERSION_CODES.O)
public void register(Object obj) {
List<SubscribeMethod> subscribeMethodList = cacheMap.get(obj);
if(subscribeMethodList == null) {
//获取所有的注解方法的封装类
subscribeMethodList = findSubscribeMethod(obj);
//将注解信息添加到map中
cacheMap.put(obj,subscribeMethodList);
}
//循环注解封装类集合
for(SubscribeMethod subscribeMethod : subscribeMethodList){
//判断是否为粘性事件
if(subscribeMethod.isStick()){
//发送粘性事件
post(stickMap.get(subscribeMethod.getType()));
}
}
}
private List<SubscribeMethod> findSubscribeMethod(Object obj) {
List<SubscribeMethod> subscribeMethodList = new ArrayList<>();
//获取订阅者的Class类型
Class<?> clzz = obj.getClass();
//获取所有注解方法
Method[] methods = clzz.getDeclaredMethods();
for(Method method : methods){
//获取带有TestSubscribe.class注解的方法
TestSubscribe testSubscribe = method.getAnnotation(TestSubscribe.class);
if(testSubscribe == null){
continue;
}
//获取方法的参数
Class<?>[] parameterTypes = method.getParameterTypes();
//判断参数的个数
if(parameterTypes.length != 1){
try {
throw new Exception("@Subscribe method must have exactly 1 parameter but has " + parameterTypes.length);
} catch (Exception e) {
e.printStackTrace();
}
}else{
//得到注解方法的threadMode
TestThreadMode testThreadMode = testSubscribe.threadMode();
//封装注解信息
SubscribeMethod subscribeMethod = new SubscribeMethod(method,testThreadMode,parameterTypes[0],testSubscribe.stick());
subscribeMethodList.add(subscribeMethod);
}
}
return subscribeMethodList;
}
//发送粘性事件
public void postStick( Object eventType) {
stickMap.put(eventType.getClass(),eventType);
}
//发送事件
public void post(final Object eventType) {
Set<Object> keySet = cacheMap.keySet();
// keySet.iterator();
for(final Object obj : keySet){
//获取注解信息
List<SubscribeMethod> subscribeMethodList = cacheMap.get(obj);
for(final SubscribeMethod subscribeMethod : subscribeMethodList){
//判断注解信息中事件与发送事件是否一致
if(subscribeMethod.getType().isAssignableFrom(eventType.getClass())){
//判断ThreadMode
switch (subscribeMethod.getThreadMode()){
case MAIN:
//主--主
if(Looper.myLooper() == Looper.getMainLooper()){
invoke(subscribeMethod,obj,eventType);
}else{
//子--主
mHandler.post(new Runnable() {
@Override
public void run() {
invoke(subscribeMethod,obj,eventType);
}
});
}
break;
case BACKGROUND:
//主---子 ExecutorService
//子---子
break;
}
}
}
}
}
private void invoke(SubscribeMethod subscribeMethod, Object obj, Object eventType) {
//调用注解方法,发送消息
Method method = subscribeMethod.getMethod();
try {
method.invoke(obj,eventType);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
这样一个简单的自定义EventBus就完了。