Android EventBus

Posted xujunjia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android EventBus相关的知识,希望对你有一定的参考价值。

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

 

Event 事件。它可以是任意类型。

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

Publisher 事件的发布者。我们可以在任意线程里发布事件,一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可。


自己从零开始写EventBus
创建EventBus
/创建Eventbus
    public static EventBus getDefault() 
        if(instance==null)
        
           synchronized (EventBus.class)
               if (instance==null)
               

                   instance=new EventBus();
               
           
        
        return instance;
    

注册

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

       
    

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

@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;
    


通信寻找注解的方法

  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();
     


    

运行起来的效果如下

技术图片

 

 

技术图片

 

 这里是源码包分享

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

以上是关于Android EventBus的主要内容,如果未能解决你的问题,请参考以下文章

EventBusEventBus 使用示例 ( 最简单的 EventBus 示例 )

EventBusEventBus 源码解析 ( 注册订阅者 | 订阅方法 | 查找订阅方法 )

EventBusEventBus 源码解析 ( 事件发送 | 线程池中执行订阅方法 )

EventBusEventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )

EventBusEventBus 源码解析 ( 注册订阅者 | 注册订阅方法详细过程 )

EventBusEventBus 源码解析 ( 事件发送 | EventBus.post 方法 | EventBus.postSingleEvent 方法 )