EventBus原理分析(简单)

灵感来源:多线程模块:http://blog.mcxiaoke.com/

下面是两个类,直接copy过去run就好了,接下来说下里面要注意的一些坑

首先,创建一个注解,用来为后续的方法筛选做准备,然后创建一个类A拥有register,post,unregister三个方法,顺便给上注解;

然后创建一个类B,构造函数就是放入A,通过一个方法findMethod将A中的所有方法都接受,这是最基础的,然后通过筛选将注解过的方法进行整合返回一个Set因为Set里面不允许重复;

在A中的register方法中运行B.findMethod(),这样就OK了,然后在A的post方法中随便传一个对象C,和返回的Set方法中的参数做匹配,然后用method.invoke方法将C传入到对应的方法并执行;

完结撒花!!!!!

public class Bus {

private static classSingletonHolder {

static finalBusINSTANCE=newBus();

}

public staticBus getDefault() {

returnSingletonHolder.INSTANCE;

}

privateMap>mMethodMap=newWeakHashMap>();

public voidregister(finalObject target) {

if(mMethodMap.containsKey(target)) {

System.err.println("target "+ target +" is already registered");

return;

}

Set methods = Helper.findAnnotatedMethods(target.getClass(),BusReceiver.class);

if(methods ==null|| methods.isEmpty()) {

return;

}

mMethodMap.put(target, methods);

}

public voidunregister(finalObject target) {

System.out.println("unregister() target="+ target);

mMethodMap.remove(target);

}

public void post(Object event) {

finalClass eventClass = event.getClass();

intsentCount =0;

for(Map.Entry> entry :mMethodMap.entrySet()) {

finalObject target = entry.getKey();

finalSet methods = entry.getValue();

if(methods ==null|| methods.isEmpty()) {

continue;

}

for(Method method : methods) {

Class parameterClass = method.getParameterTypes()[0];

if(parameterClass.isAssignableFrom(eventClass)) {

try{

System.out.println("post event to "

+ target +"."+ method.getName());

method.invoke(target, event);

sentCount++;

}catch(IllegalAccessException e) {

e.printStackTrace();

}catch(InvocationTargetException e) {

e.printStackTrace();

}

}

}

}

if(sentCount ==0) {

System.err.println("no receiver found for event: "+ event);

}

}

}




@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public@interfaceBusReceiver{

}





public classBusDemo {

public static voidmain(String[] args) {

finalBusDemo demo =newBusDemo();

Bus bus = Bus.getDefault();

bus.register(demo);

bus.post(newTom());

//        bus.post(new Object());

//        bus.post("SomeEvent");

//        bus.post(12345);

//        bus.post(new Exception("Error"));

}

@BusReceiver

public voidonReceiveRunnableNotPost(Runnable event) {

System.out.println("onReceiveRunnableNotPost() event="+ event);

}

@BusReceiver

public voidonObjectEvent(Object event) {

System.out.println("onObjectReceive() event="+ event);

}

@BusReceiver

public voidonExceptionEvent(Exception event) {

System.out.println("onExceptionEvent() event="+ event);

}

@BusReceiver

public voidonStringReceive(String event) {

System.out.println("onStringReceive() event="+ event);

}

@BusReceiver

public voidonInteger(Integer event) {

System.out.println("onInteger() event="+ event);

}

@BusReceiver

public voidonPerson(Person event) {

event.output();

}

}





final classHelper {

private static booleanshouldSkipClass(finalClass clazz) {

finalString clsName = clazz.getName();

returnObject.class.equals(clazz)

|| clsName.startsWith("java.")

|| clsName.startsWith("javax.")

|| clsName.startsWith("android.")

|| clsName.startsWith("com.android.");

}

private static booleanisAnnotatedMethod(finalMethod method,

finalClass annotation) {

// must has annotation

if(!method.isAnnotationPresent(annotation)) {

return false;

}

// must be public

if(!Modifier.isPublic(method.getModifiers())) {

return false;

}

// must not static

if(Modifier.isStatic(method.getModifiers())) {

return false;

}

// must not be volatile

// fix getDeclaredMethods bug, if method in base class,

// it returns duplicate method,

// one is normal, the other is the same but with volatile modifier

if(Modifier.isVolatile(method.getModifiers())) {

return false;

}

// must has only one parameter

if(method.getParameterTypes().length!=1) {

return false;

}

return true;

}

public staticSet findAnnotatedMethods(finalClass type,

finalClass annotation) {

Class clazz = type;

finalSet methods =newHashSet();

while(!shouldSkipClass(clazz)) {

finalMethod[] allMethods = clazz.getDeclaredMethods();

for(finalMethod method : allMethods) {

if(isAnnotatedMethod(method, annotation)) {

methods.add(method);

}

}

// search more methods in super class

clazz = clazz.getSuperclass();

}

returnmethods;

}

public static voiddumpMethod(finalMethod method) {

finalStringBuilder builder =newStringBuilder();

builder.append("------------------------------\n");

builder.append("MethodName: ").append(method.getName()).append("\n");

builder.append("ParameterTypes:{");

for(Class cls : method.getParameterTypes()) {

builder.append(cls.getName()).append(", ");

}

builder.append("}\n");

builder.append("GenericParameterTypes:{");

for(Type cls : method.getGenericParameterTypes()) {

builder.append(cls.getClass()).append(", ");

}

builder.append("}\n");

builder.append("TypeParameters:{");

for(TypeVariable cls : method.getTypeParameters()) {

builder.append(cls.getName()).append(", ");

}

builder.append("}\n");

builder.append("DeclaredAnnotations:{");

for(Annotation cls : method.getDeclaredAnnotations()) {

builder.append(cls).append(", ");

}

builder.append("}\n");

builder.append("Annotations:{");

for(Annotation cls : method.getAnnotations()) {

builder.append(cls).append(", ");

}

builder.append("}\n");

builder.append("ExceptionTypes:{");

for(Class cls : method.getExceptionTypes()) {

builder.append(cls.getName()).append(", ");

;

}

builder.append("}\n");

builder.append("ReturnType: ").append(method.getReturnType());

builder.append("\nGenericReturnType: ").append(method.getGenericReturnType());

builder.append("\nDeclaringClass: ").append(method.getDeclaringClass());

builder.append("\n");

System.out.println(builder.toString());

}

}

你可能感兴趣的:(EventBus原理分析(简单))