上文我自己写了一个观察者+反射的框架,最后发现EventBus的包体积其实不大,然后他性能优化上又作了许多措施,最终决定采用EventBus
基本使用
//api 'org.greenrobot:eventbus:3.1.1'
private static final String TAG = "xbh"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this); EventBus.getDefault().post(new Object()); } @Subscribe(threadMode = ThreadMode.MAIN) public void onLoginSuccess(Object o) { Log.i(TAG, "onLoginSuccess: "); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); }
测试了一会发现他是按照方法参数来找观察者的,post不可传递空对象,接受者方法不可无参数
索引
在前面的基础上,还可以用索引来优化,其原理是存放我们标识注解的方法
由于我是AS3.1,所以用的不是APT,而是annotationProcessor
module的build.gradle
defaultConfig下
javaCompileOptions { annotationProcessorOptions { arguments = [ eventBusIndex : 'org.greenrobot.eventbusperf.MyEventBusIndex' ] } }
dependencies下
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
make project后,会生成索引类
/** This class is generated by EventBus, do not edit. */ public class MyEventBusIndex implements SubscriberInfoIndex { private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX; static { SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>(); putIndex(new SimpleSubscriberInfo(com.example.lib.demo.MainActivity.class, true, new SubscriberMethodInfo[] { new SubscriberMethodInfo("onLoginSuccess", Object.class, ThreadMode.MAIN), })); } private static void putIndex(SubscriberInfo info) { SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info); } @Override public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) { SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass); if (info != null) { return info; } else { return null; } } }
代码中只需要在Application中注册索引文件即可,任意地方都可以,注册一次即可
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
然后,性能就提升了
EventBus和Arouter的区别
后者可以解耦接口的传递,前者在不仅可以解耦接口的传递,更可以解耦接口的实现。所以模块内部用EventBus解耦比较好,模块之间用Arouter比较好。
用EventBus不是追赶潮流人云亦云,而是要从实际需求中产生
我以前就用过EventBus,当时感觉很厉害,可以解决很多问题。后来就没用了。
后来架构能力提升了,把UI和数据解耦地特别彻底,像MVP一样,要产生大量的接口,我的解耦套路也是一样,接口已经尽可能地少了,但是规模一大,还是显得接口冗余。后来因为某些原因,重新用起了EventBus,发现他真是好用。他的核心功能是:解决接口膨胀。我以前声明的接口都被我在项目中删除了,而且接口也不需要传递了。所以这就是他的核心作用,解决接口问题。而不是明面上的组件间的通讯问题。组件间的通讯用接口就能优雅地解决了,但是接口太多就不优雅了,用了EventBus就可以让优雅做到极致。使用接口不优雅的地方在于:1.接口的传递2.接口的创建与实现。而且他做了方方面面的优化,几乎消除了反射带来的性能隐患。这也是我们要使用这个框架而不是自己简单的写一个观察者+反射的框架的原因。
其实学习任何框架都是一样,在你碰到某些需求后,自己为了方便,写了一个框架,但是发现网上已经有了,而且性能方面做的更好,这就是使用那个框架的时机了。目前rxjava我还没感觉到学习的必要性,就拿网络请求来说,我是直接拆分的网络请求,因此代码一点也不冗余。
一个新思路
前面说了我解耦UI和数据采用了EventBus,像MVP一样。我觉得MVP这些框架完全可以用EventBus来代替,免除那些冗余接口声明。可是我至今都没见过这样的思路的提出,可能已经有了我没有发现吧。
EventBus的使用注意事项
写起来这个东西很舒服,但是后来者阅读你代码的时候会很痛苦。你需要加一个todo注释,以便于别人和自己可以最快地找到你所有发消息的地方。
EventBus的tag
如果不想按参数类型发送,可以按tag发送!tag标签+post的时候加一个tag参数就可以了