美文网首页
EventBus原理分析(简单)

EventBus原理分析(简单)

作者: twohuoone | 来源:发表于2017-05-10 14:57 被阅读59次

    灵感来源:多线程模块: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原理分析(简单)

          本文链接:https://www.haomeiwen.com/subject/ozhgtxtx.html