EventBus1.0 源码解析

前言

提起EventBus,大概只要会android的人,就算没有用过也会听过。是android端有名的组件之间互相通信的框架,并且使用起来及其简单,只要10分钟就能快速上手。
但是你们在使用的时候有木有好奇,它究竟是怎么实现事件的传递的。不管你们有木有,反正我是有。所以我决定来看一下EventBus的源码,但是要我直接看EventBus最新的3.0的源码?
在这里插入图片描述
你见过玩游戏,一上来就打boss的?所以 像我这样的菜鸡,还是去看EventBus1.0的源码吧!

EventBus的使用

在观察源码之前,我想还是先来介绍一下EventBus1.0的使用。

下载地址

https://github.com/greenrobot/EventBus/releases
在这里,我们只需要去下载那个远古时代的1.0就可以了

导入工程

由于EventBus1.0的包,还是使用eclipse开发的。所以你又两个方法将他导入到我们的工程
1.先把工程转换为As工程,然后再将其作为module导入我们工程即可
2.直接将eclipse工程作为module导入
由于我比较傻白甜,用的第一种方法,花了我半个小时。。。。。。
但是也实现了目标,所以你们大家自己决定吧

使用EventBus

首先大家来看下我的目录结构。
在这里插入图片描述
然后源码

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
    }
    public void onEvent(AnyEventType event) {
        Log.d(TAG, "onEvent: 我收到消息的线程"+Thread.currentThread().getName());
        Log.d(TAG, "onEvent: 收到消息"+event.getText());
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    public void click(View view){
        startActivity(new Intent(this,SecondActivity.class));
    }
}
public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }
    public void click(View view){
        new Thread(){
            @Override
            public void run() {
                super.run();
                senMsg();
            }
        }.start();

    }

    private void senMsg() {
        Log.d("MainActivity", "run: 我运行在线程"+Thread.currentThread().getName());
        EventBus.getDefault().post(new AnyEventType("这是第二个页面传递过来的"));
    }
}
public class AnyEventType {
    private String text;
    public AnyEventType(String text) {
        this.text=text;
    }

    public String getText() {
        return text;
    }
}

ok,由于代码太过简单,这里就不在赘述。

源码解析

订阅

这次我们看源码,就按照我们的使用EventBus的顺序来吧。
我们在使用EventBus的第一件事,就是订阅事件。

 EventBus.getDefault().register(this);

首先EventBus.getDefault()

    private static final EventBus defaultInstance = new EventBus();
    
    public static EventBus getDefault() {
        return defaultInstance;
    }

EventBus全局使用一个对象,并且作为静态变量,在应用开始的时候就被创建。
这里太简单,我们接着往下看看register源码

    public enum ThreadMode {
        /** Subscriber will be called in the same thread, which is posting the event. */
        PostThread,
        /** Subscriber will be called in Android's main thread (sometimes referred to as UI thread). */
        MainThread,
        /* BackgroundThread */
    }
    
	private String defaultMethodName = "onEvent";
	
    public void register(Object subscriber) {
        register(subscriber, defaultMethodName, ThreadMode.PostThread);
    }
    
    public void registerForMainThread(Object subscriber) {
        register(subscriber, defaultMethodName, ThreadMode.MainThread);
    }

    public void register(Object subscriber, String methodName, ThreadMode threadMode) {
        List<Method> subscriberMethods = findSubscriberMethods(subscriber.getClass(), methodName);
        for (Method method : subscriberMethods) {
            Class<?> eventType = method.getParameterTypes()[0];
            subscribe(subscriber, method, eventType, threadMode);
        }
    }

这里可以看到register继续调用了对象内部的另外一个register方法,并传入了另外两个参数。

methodName这个大家根据名称应该就很容易能够猜出其功能,就是注册后,回调的方法的名称的名称,默认的方法名为"onEvent",也支持用户自己调用register方法传入自己想要的方法名。

ThreadMode这个参数是一个枚举值,EventBus一共提供了两个,一个是PostThread,就是保持消息发送方的Thread不变,类似于回调。另外一个就是MainThread,将调用方发过来的消息,传递到主线程调用,类似于Handler。

在register的方法中,我们看到了EventBus实现了一个消息列表List subscriberMethods 。并且还有一个新建Method的方法findSubscriberMethods。所以接下来我们要去看一下findSubscriberMethods的具体实现。

  private List<Method> findSubscriberMethods(Class<?> subscriberClass, String methodName) {
        String key = subscriberClass.getName() + '.' + methodName;
        List<Method> subscriberMethods;
        synchronized (methodCache) {
            //从方法缓存中,取出方法列表
            subscriberMethods = methodCache.get(key);
        }
        if (subscriberMethods != null) {
            //如果取出的方法列表不为空,则直接将方法列表抛出
            return subscriberMethods;
        }
        subscriberMethods = new ArrayList<Method>();
        Class<?> clazz = subscriberClass;
        HashSet<Class<?>> eventTypesFound = new HashSet<Class<?>>();
        while (clazz != null) {
            String name = clazz.getName();
            if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
                // Skip system classes, this just degrades performance
                break;
            }

            //获取class中所有方法
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    //获取方法的参数类型
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    if (parameterTypes.length == 1) {
                        if (eventTypesFound.add(parameterTypes[0])) {
                            //如果这个方法参数类型,在eventTypesFound没有发现,则将这个方法
                            //加入subscriberMethods
                            // Only add if not already found in a sub class
                            subscriberMethods.add(method);
                        }
                    }
                }
            }
            //查找父类。父类中也有可能注册event事件
            clazz = clazz.getSuperclass();
        }
        if (subscriberMethods.isEmpty()) {
            throw new RuntimeException("Subscriber " + subscriberClass + " has no methods called " + methodName);
        } else {
            synchronized (methodCache) {
                //将方法列表加入缓存
                methodCache.put(key, subscriberMethods);
            }
            return subscriberMethods;
        }
    }

从上面的代码中,我们很简单的能看到其中的逻辑,就是通过反射获取对象所有方法,然后根据方法名找到其中注解时间,并将其中方法加入到方法列表中。这里要注意一个点,就是如果一个方法参数的类型已经在hashset中存在,就不会再被加入到方法列表中。并且这个查找方法是一个循环,会不断的向上查找class的父类。判断是否有绑定事件。

所以根据上面的代码,我们发现如果我们给Activity添加一个父类,然后代码写成下面这样的话,绑定的消息都是可以收到的。

public abstract class BaseActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    public void onEvent(SecEventType event) {
        Log.d(TAG, "onEvent: 我是父类我收到消息的线程"+Thread.currentThread().getName());
        Log.d(TAG, "onEvent: 我是父类我收到消息"+event.getText());
    }
}
public class MainActivity extends BaseActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
        EventBus.getDefault().register(this, "OnEventTest", EventBus.ThreadMode.PostThread);
    }

    public void onEvent(AnyEventType event) {
        Log.d(TAG, "onEvent: 我收到消息的线程" + Thread.currentThread().getName());
        Log.d(TAG, "onEvent: 收到消息" + event.getText());
    }

    public void OnEventTest(String event) {
        Log.d(TAG, "OnEventTest: 我收到消息的线程" + Thread.currentThread().getName());
        Log.d(TAG, "OnEventTest: 收到消息" + event);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    public void click(View view) {
        startActivity(new Intent(this, SecondActivity.class));
    }
}

好了,findSubscriberMethods方法看完了,我们再回到register方法.

 public void register(Object subscriber, String methodName, ThreadMode threadMode) {
        List<Method> subscriberMethods = findSubscriberMethods(subscriber.getClass(), methodName);
        for (Method method : subscriberMethods) {
            Class<?> eventType = method.getParameterTypes()[0];
            subscribe(subscriber, method, eventType, threadMode);
        }
    }

作用是取出方法列表然后遍历,再去调用subscribe方法。所以再次转移阵地

    private void subscribe(Object subscriber, Method subscriberMethod, Class<?> eventType, ThreadMode threadMode) {
        //根据参数类型从map取出CopyOnWriteArrayList
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions == null) {
            //如果没有找到对应的列表,则新建一个空列表,并存入map
            subscriptions = new CopyOnWriteArrayList<Subscription>();
            subscriptionsByEventType.put(eventType, subscriptions);
        } else {
            //如果同一个对象,同一个方法名,则抛出异常。也就意味在同一个对象里面,不能写两个参数类型完全一样的订阅事件
            //但是允许同一个对象拥有多个参数不同的订阅事件
            //或者不同对象拥有同种参数类型的订阅事件
            for (Subscription subscription : subscriptions) {
                if (subscription.subscriber == subscriber) {
                    throw new RuntimeException("Subscriber " + subscriber.getClass() + " already registered to event "
                            + eventType);
                }
            }
        }
        //取消java的权限控制,这样可以访问private等的方法
        subscriberMethod.setAccessible(true);
        //将订阅相关内容封装成一个对象
        Subscription subscription = new Subscription(subscriber, subscriberMethod, threadMode);
        subscriptions.add(subscription);

        List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
        if (subscribedEvents == null) {
            //给每个订阅对象添加一个列表
            subscribedEvents = new ArrayList<Class<?>>();
            typesBySubscriber.put(subscriber, subscribedEvents);
        }
        //给订阅对象的订阅方法列表,添加一个订阅类型
        subscribedEvents.add(eventType);
    }

(这里要补充说明一下CopyOnWriteArrayList这个类,这个类和ArrayList一样,都实现了list接口。但是和ArrayList相比,增删都增加了锁,所以线程安全)
在这里我们总结一下,其实这个方法就干了两件事,涉及两个Map,一个map是以绑定对象为维度,保存订阅的方法。另外一个map是以绑定方法为维度,保存订阅的相关的对象,订阅方法,以及ThreadMode。

其实走到这里订阅相关的方法就已经走完了。那我们就来分析一下,如果按照我们之前写的方法subscriptionsByEventType这个map中应该有三个subscriptions。而typesBySubscriber中只有一个subscribedEvents,然后subscribedEvents中包含了三个方法。
我们将register方法改造一下,打印出我们这里两个hashmap

    public void register(Object subscriber, String methodName, ThreadMode threadMode) {
        List<Method> subscriberMethods = findSubscriberMethods(subscriber.getClass(), methodName);
        for (Method method : subscriberMethods) {
            Class<?> eventType = method.getParameterTypes()[0];
            subscribe(subscriber, method, eventType, threadMode);
        }

        for (CopyOnWriteArrayList<Subscription> bean :
                subscriptionsByEventType.values()) {
                Log.d("EventBus","subscriptionsByEventType==");
            for (int i=0;i<bean.size();i++){
                Log.d("EventBus","=========================="+bean.get(i).subscriber+"."+bean.get(i).method);
            }
        }

        for (List<Class<?>> bean :
                typesBySubscriber.values()) {
            Log.d("EventBus","typesBySubscriber==");
            for (int i=0;i<bean.size();i++){
                Log.d("EventBus","=========================="+bean.get(i).getName());
            }
        }
    }

运行后我们获得了下面的结果

//第一次调用订阅
subscriptionsByEventType==
==========================com.lanlengran.eventbus10test.MainActivity.onEvent
subscriptionsByEventType==
==========================com.lanlengran.eventbus10test.MainActivity.onEvent
typesBySubscriber==
==========================com.lanlengran.eventbus10test.AnyEventType
==========================com.lanlengran.eventbus10test.SecEventType



//第二次调用订阅
subscriptionsByEventType==
==========================com.lanlengran.eventbus10test.MainActivity.onEvent
subscriptionsByEventType==
==========================com.lanlengran.eventbus10test.MainActivity.onEvent
subscriptionsByEventType==
==========================com.lanlengran.eventbus10test.MainActivity.OnEventTest
typesBySubscriber==
==========================com.lanlengran.eventbus10test.AnyEventType
==========================com.lanlengran.eventbus10test.SecEventType
==========================java.lang.String

好了,果然和我们预料的一样,第一次的时候,直接只绑定了MainActivity的方法和BaseActivity的方法,所以subscriptionsByEventType里包含两个对象,typesBySubscriber的里面只包含一个列表,但是列表里面有两个方法。

以此类推,在后面又调用注册的时候,方法变成了三个。

ok,订阅过程分析完毕。

发布消息

EventBus的发布消息也是极其非常简单的只需要

    private void senMsg() {
        Log.d("MainActivity", "run: 我运行在线程"+Thread.currentThread().getName());
        EventBus.getDefault().post(new AnyEventType("这是第二个页面传递过来的"));
        EventBus.getDefault().post(new SecEventType("这是第二个页面传递过来的"));
        EventBus.getDefault().post("233333");
    }

你看看,一行代码,一个消息,不要太简单。我三行代码三个消息。
所以,惯例,我们从post方法看起。

    private final ThreadLocal<List<Object>> currentThreadEventQueue = new ThreadLocal<List<Object>>() {
        @Override
        protected List<Object> initialValue() {
            return new ArrayList<Object>();
        }
    };
    
/**
     * Posts the given event to the event bus.
     */
    public void post(Object event) {
        List<Object> eventQueue = currentThreadEventQueue.get();
        eventQueue.add(event);

        BooleanWrapper isPosting = currentThreadIsPosting.get();
        //如果正在分发消息,则直接return
        if (isPosting.value) {
            return;
        } else {
            isPosting.value = true;
            try {
                while (!eventQueue.isEmpty()) {
                    //抛出列表的第一项,并从列表中移除
                    postSingleEvent(eventQueue.remove(0));
                }
            } finally {
                isPosting.value = false;
            }
        }
    }

这里第一句话,可能部分人不是很懂,就是这个currentThreadEventQueue,这个currentThreadEventQueue是一个ThreadLocal对象。那么这个ThreadLocal如果你看过我前面的handler的源码解析的文章,那么你就应该清楚他的作用是啥。在这里我在解释一下,ThreadLocal可以保证每个thread中的变量互补干扰,即使同名。
也就是说,每个线程中,都会有自己单独的List eventQueue。

这里除了ThreadLocal这个知识点以外,实在没有啥好讲的。其中会把消息传递到postSingleEvent方法。

    private void postSingleEvent(Object event) throws Error {
        //查找到event事件类的包含自己,以及所有的父类,并将其存入列表中
        List<Class<?>> eventTypes = findEventTypes(event.getClass());
        boolean subscriptionFound = false;
        //event事件有多少个父类
        int countTypes = eventTypes.size();
        for (int h = 0; h < countTypes; h++) {
            Class<?> clazz = eventTypes.get(h);
            CopyOnWriteArrayList<Subscription> subscriptions;
            synchronized (this) {
                subscriptions = subscriptionsByEventType.get(clazz);
            }
            if (subscriptions != null) {
                //一个event事件可能会被多个对象订阅,所以需要遍历
                for (Subscription subscription : subscriptions) {
                    if (subscription.threadMode == ThreadMode.PostThread) {
                        postToSubscribtion(subscription, event);
                    } else if (subscription.threadMode == ThreadMode.MainThread) {
                        mainThreadPoster.enqueue(event, subscription);
                    } else {
                        throw new IllegalStateException("Unknown thread mode: " + subscription.threadMode);
                    }
                }
                subscriptionFound = true;
            }
        }
        if (!subscriptionFound) {
            Log.d(TAG, "No subscripers registered for event " + event.getClass());
        }
    }

这里的逻辑也很简单了,就是首先找出event事件的父类,然后再去我们订阅的时候用event事件为key的map中去找对应的订阅信息。最后再根据不同的ThreadMode调用不同的方法。
首先我们看下ThreadMode.PostThread的处理方法postToSubscribtion

    static void postToSubscribtion(Subscription subscription, Object event) throws Error {
        try {
            subscription.method.invoke(subscription.subscriber, event);
        } catch (InvocationTargetException e) {
            Throwable cause = e.getCause();
            Log.e(TAG, "Could not dispatch event: " + event.getClass() + " to subscribing class "
                    + subscription.subscriber.getClass(), cause);
            if (cause instanceof Error) {
                throw (Error) cause;
            }
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("Unexpected exception", e);
        }
    }

额, 这。。。。
这实际上就一句话,就是用反射执行了这个方法,所以我们还是去看看ThreadMode.MainThread的方法吧。

首先我们需要关注一下,这个mainThreadPoster是个什么玩意。

    private PostViaHandler mainThreadPoster;

    public EventBus() {
        subscriptionsByEventType = new HashMap<Class<?>, CopyOnWriteArrayList<Subscription>>();
        typesBySubscriber = new HashMap<Object, List<Class<?>>>();
        mainThreadPoster = new PostViaHandler(Looper.getMainLooper());
    }
    final static class PostViaHandler extends Handler {

        PostViaHandler(Looper looper) {
            super(looper);
        }

        void enqueue(Object event, Subscription subscription) {
            PendingPost pendingPost = PendingPost.obtainPendingPost(event, subscription);
            Message message = obtainMessage();
            message.obj = pendingPost;
            if (!sendMessage(message)) {
                throw new RuntimeException("Could not send handler message");
            }
        }

        @Override
        public void handleMessage(Message msg) {
            PendingPost pendingPost = (PendingPost) msg.obj;
            Object event = pendingPost.event;
            Subscription subscription = pendingPost.subscription;
            PendingPost.releasePendingPost(pendingPost);
            postToSubscribtion(subscription, event);
        }

    }

好嘛,也没啥,就是封装了一个handler。而所谓的ThreadMode.MainThread中执行的方法,不过是通过handler将事件传递了出去,然后再handleMessage中调用了,我们前面看到的postToSubscribtion方法。执行了对应的方法。

取消订阅

eventbus的取消订阅的方法也非常简单,只需要调用下面的代码即可。

EventBus.getDefault().unregister(this);

所以我们来看一下unregister的相关逻辑

    /**
     * Unregisters the given subscriber from all event classes.
     */
    public synchronized void unregister(Object subscriber) {
        List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
        if (subscribedTypes != null) {
            for (Class<?> eventType : subscribedTypes) {
                unubscribeByEventType(subscriber, eventType);
            }
            typesBySubscriber.remove(subscriber);
        } else {
            Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
        }
    }

上面代码的意思很明确,通过订阅对象查询到所有的订阅方法,然后依次调用unubscribeByEventType。

    /**
     * Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber.
     */
    private void unubscribeByEventType(Object subscriber, Class<?> eventType) {
        List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions != null) {
            int size = subscriptions.size();
            for (int i = 0; i < size; i++) {
                if (subscriptions.get(i).subscriber == subscriber) {
                    subscriptions.remove(i);
                    i--;
                    size--;
                }
            }
        }
    }

这里代码的逻辑也非常明确,就是从subscriptionsByEventType中移除该对象对应的订阅方法。
而unregister方法,在执行完unubscribeByEventType以后,也会通过 typesBySubscriber.remove(subscriber);移除在typesBySubscriber中的对象。

所以总结一下,取消订阅的方法就是移除subscriptionsByEventType和typesBySubscriber中的与订阅对象相关的内容。

总结

我们从上到下查看了eventbus从订阅到发布到取消订阅的相关代码。发现代码的核心就是在subscriptionsByEventType和typesBySubscriber这两个map上面。
subscriptionsByEventType是通过订阅者保存相关的订阅信息,用来取消订阅的时候查找到所有的订阅方法。
而subscriptionsByEventType则是通过订阅的参数类型即event类型来保存相关的订阅信息,用来在发布事件的时候查找到相关的订阅者以及订阅方法

拓展

在阅读了EventBus的源码以后,有种作者行,我也行的错觉。所以就山寨了一个EventBus,去除了一切的线程安全相关,以及速度优化相关,仅展示其基本原理。
以下是山寨EventBus代码

public class MyEventBus {
    private static MyEventBus instance = new MyEventBus();
    private static String defaultMthodName = "onEvent";
    private HashMap<Object, List<Method>> methodListByRegister = new HashMap<>();
    private HashMap<Object, List<Subscription>> methodListByEvent = new HashMap<>();
    private List<Object> eventQueue = new ArrayList<>();
    boolean isPost = false;

    private static final String TAG = "MyEventBus";

    public static MyEventBus getDefault() {
        return instance;
    }



    public enum ThreadMode {
        PostThread, MainThread
    }

    public void register(Object register) {
        register(register, ThreadMode.PostThread, defaultMthodName);
    }

    public void registerForMainThread(Object register) {
        register(register, ThreadMode.MainThread, defaultMthodName);
    }

    public void register(Object register, ThreadMode threadMode, String methodName) {
        List<Method> methodList = findRegistserMethod(register, methodName);
        for (Method method : methodList) {
            subscribeMethod(register, method, threadMode);
        }
    }

    private void subscribeMethod(Object register, Method method, ThreadMode threadMode) {
        List<Subscription> subscriptionList = methodListByEvent.get(method.getParameterTypes()[0]);
        if (subscriptionList == null) {
            subscriptionList = new ArrayList<>();
            methodListByEvent.put(method.getParameterTypes()[0], subscriptionList);
        }
        Subscription subscription = new Subscription(register, method, threadMode);
        subscriptionList.add(subscription);

        List<Method> methods = methodListByRegister.get(register);
        if (methods == null) {
            methods = new ArrayList<>();
            methodListByRegister.put(register, methods);
        }
        methods.add(method);

    }

    private List<Method> findRegistserMethod(Object register, String methodName) {
        Class registerClass = register.getClass();
        List<Method> methodList = new ArrayList<>();
        HashSet<Class> hashSet = new HashSet<>();
        while (registerClass != null) {
            if (registerClass.getName().startsWith("java.") || registerClass.getName().startsWith("android.")
                    || registerClass.getName().startsWith("javax.")) {
                break;
            }
            Method[] methods = registerClass.getMethods();
            for (Method method : methods) {

                if (method.getName().equals(methodName)) {
                    Class[] params = method.getParameterTypes();
                    if (params.length == 1) {
                        if (hashSet.add(params[0])) {
                            methodList.add(method);
                        }
                    }
                }

            }
            registerClass = registerClass.getSuperclass();
        }
        return methodList;
    }

    public void post(Object event) {
        eventQueue.add(event);
        isPost = true;
        while (eventQueue.size() > 0) {
            Object sendEvent = eventQueue.remove(0);
            if (sendEvent == null) {
                continue;
            }
            List<Subscription> subscriptionList = methodListByEvent.get(event.getClass());
            if (subscriptionList != null) {
                for (Subscription subscription : subscriptionList) {
                    try {
                        if (subscription.threadMode == ThreadMode.PostThread) {
                            subscription.method.invoke(subscription.register, event);
                        } else if (subscription.threadMode == ThreadMode.MainThread) {
                            // 暂未实现
                            subscription.method.invoke(subscription.register, event);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        Log.e(TAG, "post: " + e.getMessage());
                    }

                }
            }
        }
        isPost = false;
    }

    public void unregister(Object register) {
        List<Method> methodList= methodListByRegister.get(register);
        if (methodList==null){
            return;
        }
        for (Method method:methodList){
            List<Subscription> subscriptionList=methodListByEvent.get(method.getParameterTypes()[0]);
            for (int i=0;i<subscriptionList.size();i++){
                Subscription subscription=subscriptionList.get(i);
                if (subscription.register==register){
                    subscriptionList.remove(subscription);
                    i--;
                }
            }
        }
        methodListByRegister.remove(register);
    }

    private static class Subscription {
        public Object register;
        public Method method;
        public ThreadMode threadMode;

        public Subscription(Object register, Method method, ThreadMode threadMode) {
            this.register = register;
            this.method = method;
            this.threadMode = threadMode;
        }
    }
}

感想

至此,我们就看完了整个EventBus1.0的实现细节,以及相关的订阅和发布消息。可以看出来整个的逻辑还是非常的清晰的,代码非常的易懂,并且里面用到的内容也是我们经常见到的。
但是我现在看到这些代码,还是只能知其然,不能知其所以然。果然自己还是好菜啊
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值