EventBus框架核心原理

EventBus 框架解耦和核心原理(事件總線,訂閱,取消訂閱,解耦,根據自己看源碼的理解手寫一個簡潔版的EventBus)

下面是EventBus類的核心代碼
 /**
         *  注入對象(將對象添加到事件總線中去)
         * @param obj
         */
        public void regist(Object obj) {
            List<SubscribeMethod> subscribeMethods = mCacheMap.get(obj);
            if (subscribeMethods == null) {
                subscribeMethods = findSubscribeMethod(obj);
                mCacheMap.put(obj, subscribeMethods);
            }
        }
 /**
         * 根據注入對象把帶有Subsribe註解的方法封裝到事件總線中去
         * @param obj
         * @return
         */
        private List<SubscribeMethod> findSubscribeMethod(Object obj) {
            List<SubscribeMethod> list = new ArrayList<>();
            Class<?> aClass = obj.getClass();
            while (aClass != null) {
                //獲取當前類聲明的方法
                Method[] methods = aClass.getDeclaredMethods();
                for (Method method : methods) {
                    //獲取定義的註解類型
                    Subscribe subscribe = method.getAnnotation(Subscribe.class);
                    if (subscribe == null) {
                        continue;
                    }
                     //獲取方法中的參數類型
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    //如果參數類型長度不是1就給用戶拋異常(傳遞多個參數可以放到MessageEvent對象中)
                    if (parameterTypes.length != 1) {
                        throw new IllegalArgumentException("EventBus params only one");
                    }
                    //獲取註解模式
                    ThreadMode threadMode = subscribe.threadMode();
                    //創建事件總線中的實體類
                    SubscribeMethod subscribeMethod = new SubscribeMethod(method, threadMode, parameterTypes[0]);
                    list.add(subscribeMethod);

                }
                aClass = aClass.getSuperclass();
            }

            return list;
        }
        
        /**
         *  被觀察者發出的事件
         * @param type
         */
        public void post(Object type) {
            Set<Object> keySet = mCacheMap.keySet();
            Iterator<Object> iterator = keySet.iterator();
            while (iterator.hasNext()) {
                Object obj = iterator.next();
                //獲取到事件總線中對應的注入對象中對應的事件
                List<SubscribeMethod> subscribeMethods = mCacheMap.get(obj);
                  for (SubscribeMethod subscribeMethod : subscribeMethods) {
                    //判斷參數類型是否是繼承關係
                    if (subscribeMethod.getType().isAssignableFrom(type.getClass())) {
                        invoke(subscribeMethod, obj, type);
                    }
                }
            }
        }
private void invoke(SubscribeMethod subscribeMethod, Object obj, Object type) {
            Method method = subscribeMethod.getMethod();
            //如果是主線程  invoke  ThreadMode == ThreadMode.MAIN 的方法
            if (isMainThread()){
                if (subscribeMethod.getThreadMode() == ThreadMode.MAIN){
                    try {
                        method.invoke(obj, type);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
                 } else{
                //如果是主線程  invoke  ThreadMode == ThreadMode.BACKGOUND 的方法
                if (subscribeMethod.getThreadMode() == ThreadMode.BACKGOUND){
                    try {
                        method.invoke(obj, type);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
 /**
         *  註銷  把事件總線中的注入對象對應的事件清空  意味着收不到EventBus發送出來的消息了
         */
        public void unRegist(Object obj) {
            mCacheMap.remove(obj);
        }

        /**
         * 判斷當前線程是否是主線程
         * @return
         */
        public boolean isMainThread() {
            return Looper.getMainLooper() == Looper.myLooper();
        }
自定義註解類(ThraedMode就是一個枚舉)
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
	//默認是主線程(要可以手動設置成子線程或者其他的模式)
    ThreadMode threadMode() default ThreadMode.MAIN;
}

事件總線中的實體類(主要封裝了Method,TheadMode,Type(參數類型))
 private Method method;
    private ThreadMode threadMode;
    private Class<?> type;

    public SubscribeMethod(Method method, ThreadMode threadMode, Class<?> type) {
        this.method = method;
        this.threadMode = threadMode;
        this.type = type;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public ThreadMode getThreadMode() {
        return threadMode;
    }

    public void setThreadMode(ThreadMode threadMode) {
        this.threadMode = threadMode;
    }

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

    public void setType(Class<?> type) {
        this.type = type;
    }
下面是發送和接收
 //Aclass
 @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event){
        Log.d("====>","主線程:"+event.toString());
    }

    @Subscribe(threadMode = ThreadMode.BACKGOUND)
    public void onMessageEvent1(MessageEvent event){
        Log.d("====>","子線程:"+event.toString());
    }
-------------------------------
//Bclass
 public void main(View view) {
        EventBus.getDefault().post(new MessageEvent("羅大佑","唱歌"));
    }

    public void sub(View view) {
        new Thread(){
            @Override
            public void run() {
                super.run();
                EventBus.getDefault().post(new MessageEvent("科比","打籃球"));
            }
        }.start();
    }

運行結果如下
2019-10-10 10:15:00.834 6614-6614/com.example.eventbuspro D/====1>: MessageEvent{name='羅大佑', hobby='唱歌'}
2019-10-10 10:15:02.202 6614-6664/com.example.eventbuspro D/====2>: MessageEvent{name='科比', hobby='打籃球'}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章