7

Android 框架炼成 教你如何写组件间通信框架EventBus

 3 years ago
source link: https://blog.csdn.net/lmj623565791/article/details/41096639
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/41096639  ,本文出自:【张鸿洋的博客】

关于Eventbus的介绍,前面已经有两篇:Android EventBus实战 没听过你就out了Android EventBus源码解析 带你深入理解EventBus , 如果你觉得还有问题,没关系,接下来我带大家手把手打造从无到有的编写这样的框架~~~

首先我们回顾一下,这玩意就是在register时,扫描类中复合命名规范的方法,存到一个map,然后post的时候,查找到匹配的方法,反射调用;好,那么根据这一句话,我们就开始编写框架之旅~~~

2、依然是原来的配方

以下出现的实例代码和Android EventBus实战 没听过你就out了基本一致,所以我就贴出部分

1、ItemListFragment

2、ItemDetailFragment

可以看到,我们在ItemListFragment里面使用了:

EventBus.getInstatnce().post(new ItemListEvent(Item.ITEMS));去发布了一个事件,然后更新了我们的列表;

点击Item的时候,使用EventBus.getInstatnce().post(getListView().getItemAtPosition(position));发布了一个事件,更新了我们的ItemDetailFragment的列表;

效果图和之前的一摸一样~~~

但是请注意,现在我们用的是EventBus.getInstatnce();并发是EventBus.getDefault();并且看下包名import com.zhy.eventbus.EventBus;

我想你应该明白了,这是我们自己写的类来实现的~~~~

好了,接下来就带大家一起实现这个类~~

ps :以上代码和效果图,完全是为了博客的完整性,勿见怪~~

3、无中生有

1、getInstance

我们这里为了方便,直接简单粗暴的使用恶汉模式创建单例:

然后在构造方法中初始化了一个mHandler,没错,它就是用来在处理在UI线程调用方法的。

接下来看register

2、register

可以看到我们使用了一个Map存储所有的方法,key为参数的类型class;value为CopyOnWriteArrayList<SubscribeMethod>

这里我们封装了一个SubscribeMethod,这个里面存储了我们需要运行方法的所有参数,毕竟我们运行时,需要该方法,该方法所在的对象,以及在什么线程运行;三个对象足以,当然也缺一不可了~~

register里面,我们遍历该类的所有方法,找到onEvent开头的,封装成SubscribeMethod,存在Map里面,当然了,一个参数类型对应很多方法,所以value是个CopyOnWriteArrayList。

扫描完成,我们就完成了将方法的存储。

还有一点,我们这里默认在UI线程执行,如果方法是onEventAsync则认为在子线程执行,我们也只支持这两种模式,简化一点~

3、post

我们这里学习了源码,也搞了个当前线程中的变量,存储了一个事件队列以及事件的状态;

最终发布的事件先加入到事件队列,然后再取出来调用postEvent

postEvent也很简单,直接根据参数类型,去map改到该方法,根据其threadMode,如果在UI线程,则判断当前线程,如果是UI线程,直接调用,否则通过handler执行;

如果非UI线程,这里我们直接开启了一个Thread去执行;

invokeMethod很简单,就是反射调用方法了~

4、unregister

unregister时,由于我们没有存任何的辅助状态,我们只能再去遍历了方法了~~不过通过这个,也能反应出EventBus内部好几个Map的作用了~~

并且,我们也不支持一些状态的查询,还是因为我们没有存一些辅助状态,例如isRegister等等。

到此,我们的EventBus就写好了,100多行代码,肯定没有EventBus健壮,主要目的还是学习人家的思想,经过自己写了这么个类,我相信对于EventBus的理解就更深刻了~面试的时候,恨不得拿只笔写给面试官看,哈哈~~

5、EventBus最佳实践

前面的文章,很多朋友问,如果我多个方法参数都一样,岂不是post一个此参数,会多个方法调用;而此时我想调用指定的方法怎么办?

还有,项目中会有很多地方去接收List参数,而List<T>中的泛型是不一致的,所以也可能post(List)时,会调用很多方法,造成出错。

的确,上述,不加处理肯定会出现;

但是,推荐大家在使用EventBus的时候,创建一个事件类,把你的每一个参数(或者可能发生冲突的参数),封装成一个类:

这样的话,就不会发生什么调用冲突了~~

源码点击下载

我建了一个QQ群,方便大家交流。群号:55032675

----------------------------------------------------------------------------------------------------------

博主部分视频已经上线,如果你不喜欢枯燥的文本,请猛戳(初录,期待您的支持):

1、高仿微信5.2.1主界面及消息提醒

2、高仿QQ5.0侧滑

3、Android智能机器人“小慕”的实现


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK