EventBus的手写

在上一篇文章我讲了EventBus源码,现在我们来手写一下EventBus
使用

MainActiviity

public class MainActivity extends AppCompatActivity {

    private TextView mTv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 注册,思考为什么要注册?
        EventBus.getDefault().register(this);

        // 进入测试界面
        mTv = (TextView) findViewById(R.id.test_tv);
        mTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,TestActivity.class);
                startActivity(intent);
            }
        });
    }

    /**
     * threadMode 执行的线程方式
     * priority 执行的优先级,值越大优先级越高
     * sticky 粘性事件
     */
    @Subscribe(threadMode = ThreadMode.MAIN,priority = 100,sticky = true)
    public void test2(String msg){
        // 如果有一个地方用 EventBus 发送一个 String 对象,那么这个方法就会被执行
        Log.e("TAG","msg2 = "+msg);
        mTv.setText(msg);
    }


    /**
     * threadMode 执行的线程方式
     * priority 执行的优先级
     * sticky 粘性事件
     */
    @Subscribe(threadMode = ThreadMode.MAIN,priority = 50,sticky = true)
    public void test1(String msg){
        // 如果有一个地方用 EventBus 发送一个 String 对象,那么这个方法就会被执行
        Log.e("TAG","msg1 = "+msg);
        mTv.setText(msg);
    }

    @Override
    protected void onDestroy() {
        // 解绑,思考为什么要解绑?
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}

TestActivity

public class TestActivity extends AppCompatActivity{
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.test_tv).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post("test_content");
            }
        });
    }
}

首先拷贝一些用到的类Subscribe注解,SubscriberMethod,Subscription,ThreadMode,这些源码中都有就不拷贝了

开始手写EventBus

public class EventBus {
    private static volatile EventBus defaultInstance;
    // subscriptionsByEventType 这个集合存放的是?
    // key 是 Event 参数的类
    // value 存放的是 Subscription 的集合列表
    // Subscription 包含两个属性,一个是 subscriber 订阅者(反射执行对象),一个是 SubscriberMethod 注解方法的所有属性参数值
    private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
    // typesBySubscriber 这个集合存放的是?
    // key 是所有的订阅者
    // value 是所有订阅者里面方法的参数的class
    private final Map<Object, List<Class<?>>> typesBySubscriber;

    private EventBus() {
        subscriptionsByEventType = new HashMap<>();
        typesBySubscriber = new HashMap<>();
    }

    //单例设计模式
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }

    /**
     * 注册
     */
    public void register(Object object) {
        //1.解析所有的方法封装成SubscibeMethod集合
        Class<?> objectClass = object.getClass();
        List<SubscriberMethod> subscriberMethods = new ArrayList<>();
        //1.2.获得所有方法
        Method[] methods = objectClass.getDeclaredMethods();
        for (Method method : methods) {
            //1.3.获得所有被Subscribe所修饰的注解的方法
            Subscribe subscribe = method.getAnnotation(Subscribe.class);
            if (subscribe != null) {
                //获得注解参数的类
                Class<?>[] parameterTypes = method.getParameterTypes();
                Class<?> eventType = parameterTypes[0];
                SubscriberMethod subscriberMethod = new SubscriberMethod(method
                        , eventType, subscribe.threadMode(), subscribe.priority(), subscribe.sticky());
                subscriberMethods.add(subscriberMethod);
            }
        }
        //2.按照一定顺序存放到 subscriptionsByEventType 里面去
        for (SubscriberMethod method : subscriberMethods) {
            subscriber(object, method);
        }

    }

    //2.按照一定顺序存放到 subscriptionsByEventType 里面去
    private void subscriber(Object object, SubscriberMethod subscriberMethod) {
        Class<?> eventType = subscriberMethod.eventType;
        //默认是空
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList<>();
            subscriptionsByEventType.put(eventType, subscriptions);
        }
        //添加到subscriptionsByEventType
        Subscription subscription = new Subscription(object, subscriberMethod);
        subscriptions.add(subscription);

        //3.添加到typesBySubscriber,用来移除的
        List<Class<?>> subscribedEvents = typesBySubscriber.get(object);
        if (subscribedEvents == null) {
            subscribedEvents = new ArrayList<>();
            typesBySubscriber.put(object, subscribedEvents);
        }

        if (!subscribedEvents.contains(eventType)) {
            subscribedEvents.add(eventType);
        }

    }

    /**
     * 解注册
     */
    public void unregister(Object object) {
        List<Class<?>> eventTypes = typesBySubscriber.get(object);
        if (eventTypes != null) {
            for (Class<?> eventType : eventTypes) {//String.class
                removeObject(eventType, object);
            }
        }
    }

    private void removeObject(Class<?> eventType, Object object) {
        List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions != null) {
            int size = subscriptions.size();
            for (int i = 0; i < size; i++) {
                Subscription subscription = subscriptions.get(i);
                if (subscription.subscriber == object) {
                    // 将订阅信息从集合中移除
                    subscriptions.remove(i);
                    i--;
                    size--;
                }
            }
        }
    }

    //发送
    public void post(Object event) {
        // 遍历 subscriptionsByEventType,找到符合的方法调用方法的 method.invoke() 执行。要注意线程切换
        Class<?> eventType = event.getClass();
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions != null) {
            for (Subscription subscription : subscriptions) {
                executeMethod(subscription, event);
            }
        }
    }

    private void executeMethod(final Subscription subscription, final Object event) {
        ThreadMode threadMode = subscription.subscriberMethod.threadMode;
        boolean isMainThread = Looper.getMainLooper() == Looper.myLooper();
        switch (threadMode) {
            case POSTING:
                invokeMethod(subscription, event);
                break;
            case MAIN:
                if (isMainThread) {
                    invokeMethod(subscription, event);
                } else {
                    Handler handler = new Handler(Looper.getMainLooper());
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            invokeMethod(subscription, event);
                        }
                    });
                }
                break;
            case BACKGROUND:
                if (!isMainThread) {
                    invokeMethod(subscription, event);
                } else {//自己开一个子线程去更新
                    AsyncPoster.enqueue(subscription, event);
                }
                break;
            case ASYNC:
                AsyncPoster.enqueue(subscription, event);
                break;
        }
    }

    private void invokeMethod(Subscription subscription, Object event) {
        try {
            subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

AsyncPoster:线程池执行异步任务

public class AsyncPoster implements Runnable {
    Subscription subscription;
    Object event;
    //线程池
    private final static ExecutorService executorService = Executors.newCachedThreadPool();

    public AsyncPoster(Subscription subscription, Object event) {
        this.subscription = subscription;
        this.event = event;
    }

    /**
     * 执行异步
     */
    public static void enqueue(Subscription subscription, Object event) {
        AsyncPoster asyncPoster = new AsyncPoster(subscription, event);
        executorService.execute(asyncPoster);
    }

    @Override
    public void run() {
        try {
            subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值