Android EventBus

当咱们进行项目开发的时候,每每是须要应用程序的各组件、组件与后台线程间进行通讯,好比在子线程中进行请求数据,当数据请求完毕后经过Handler或者是广播通知UI,而两个Fragment之家能够经过Listener进行通讯等等。当咱们的项目愈来愈复杂,使用Intent、Handler、Broadcast进行模块间通讯、模块与后台线程进行通讯时,代码量大,并且高度耦合。

 

Event 事件。它能够是任意类型。java

Subscriber 事件订阅者。在EventBus3.0以前咱们必须定义以onEvent开头的那几个方法,分别是onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,而在3.0以后事件处理的方法名能够随意取,不过须要加上注解@subscribe(),而且指定线程模型,默认是POSTING。android

Publisher 事件的发布者。咱们能够在任意线程里发布事件,通常状况下,使用EventBus.getDefault()就能够获得一个EventBus对象,而后再调用post(Object)方法便可。ide


本身从零开始写EventBus
建立EventBus
/建立Eventbus
    public static EventBus getDefault() {
        if(instance==null)
        {
           synchronized (EventBus.class){
               if (instance==null)
               {

                   instance=new EventBus();
               }
           }
        }
        return instance;
    }

注册oop

//注册
    public void register(Object obj) {
       List<SubscribleMethod> list =cachemap.get(obj);
       if(list==null)
       {
         list =findSubscribleMethod(obj);
            cachemap.put(obj,list);

       }
    }

通讯之间的寻找经过注解的方法寻找,这里为默认方式post

@Subcrible(threadMode= ThreadMode.MAIN)
、

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subcrible {

ThreadMode threadMode() default ThreadMode.MAIN;

}
 
 
Subcrible的各类状态
package com.example.eventbus;

import java.lang.reflect.Method;

public class SubscribleMethod {


    //回调方法
    private Method mMethod;
    //线程模式
    private ThreadMode mthreadMode;

    //方法中的参数
    private  Class<?> type;

    public SubscribleMethod(Method mMethod, ThreadMode mthreadMode, Class<?> type) {
        this.mMethod = mMethod;
        this.mthreadMode = mthreadMode;
        this.type = type;
    }

    public void setmMethod(Method mMethod) {
        this.mMethod = mMethod;
    }

    public void setMthreadMode(ThreadMode mthreadMode) {
        this.mthreadMode = mthreadMode;
    }

    public Method getmMethod() {
        return mMethod;
    }

    public ThreadMode getMthreadMode() {
        return mthreadMode;
    }

    public Class<?> getType() {
        return type;
    }

    public void setType(Class<?> type) {
        this.type = type;
    }


}

通讯寻找注解的方法this

  private List<SubscribleMethod> findSubscribleMethod(Object obj) {
         List<SubscribleMethod> list=new ArrayList<>();
         Class< ?> clazz =obj.getClass();
         Method[] methods =clazz.getDeclaredMethods();
         while (clazz!=null)
         {
             //找父类的时候须要先判断一下是否系统级别的父类
             String name=clazz.getName();
             if(name.startsWith("java.")||name.startsWith("javax.")
           ||name.startsWith("android"))
             {
                 break;
             }
             for (Method method:methods)
             {
                 //找到带有Subcrible 注解的方法
                 Subcrible subcrible=method.getAnnotation(Subcrible.class);
                 if (subcrible==null)
                 {
                     continue;
                 }
                 //判断subscrible 注解的方法中的参数类
                 Class<?>[] type=   method.getParameterTypes();
                 if(type.length!=1)
                 {
                     Log.e("TAG", "eventBus only accept one para  " );
                 }
                 ThreadMode threadMode=subcrible.threadMode();
                 SubscribleMethod subscribleMethod=new SubscribleMethod(method,threadMode,type[0]);
                 list.add(subscribleMethod);
             }
                   clazz= clazz.getSuperclass();
         }

        return list;
    }

    public void post(final Object type) {

       //直接循环 Map里的方法 ,找到相对得而后回调
        Set<Object> set =cachemap.keySet();
        Iterator<Object> iterator=set.iterator();
        while (iterator.hasNext())
        {
            final Object  obj =iterator.next();
            List<SubscribleMethod>list=cachemap.get(obj);
            for (final SubscribleMethod subscribleMethod:list){
                //a(if 条件得对象)对象所对应得类信息是否是b if条件后面得对象对象所对应得接口或者父类
                if (subscribleMethod.getType().isAssignableFrom(type.getClass()))
                {
                    switch (subscribleMethod.getMthreadMode())
                    {
                        case MAIN:
                            //主线程 -主线程
                            if (Looper.myLooper()==Looper.getMainLooper())
                            {
                                invoke(subscribleMethod,obj,type);
                            }
                            else {
                                //子线程 -主线程
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        invoke(subscribleMethod,obj,type);
                                    }
                                });
                            }
                            break;

                    }



                }

            }


        }
    }

    private void invoke(SubscribleMethod subscribleMethod, Object obj, Object type) {
       Method method=subscribleMethod.getmMethod();
     try {
         method.invoke(obj,type);
     }catch (IllegalAccessException e)
     {
         e.printStackTrace();
     }
     catch (InvocationTargetException e)
     {
         e.printStackTrace();
     }


    }
}

运行起来的效果以下spa

 

 

 

 这里是源码包分享线程

连接:https://pan.baidu.com/s/1CnTNCndQHizktb4e338BnA
提取码:vcvx
复制这段内容后打开百度网盘手机App,操做更方便哦code

相关文章
相关标签/搜索