EventBus 大部分人都用过了,就不再介绍了,本篇主要讲一下实际项目中EventBus的封装过程。
1、正常用法
根据官网的介绍和网上博客的讲解,一般用法如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
/**
* 2.x 方法必须以onEvent开头
* @param event
*/
public void onEventMainThread(MessageEvent event) {
}
/**
* 3.0 方法名可以自定义
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
}
}
可以看到,2.x版本使用时需要手动写onEvent
开头的方法来接收消息,这种用法明显有很大的隐患,如果不小心写错、改错或被误删就会出bug,也不好维护。所以3.0针对这块做了优化,使用注解更符合Java风格,而且方法名可以自定义,这样就消除了2.x的弊端。
以上是EventBus的正常用法,一般项目中很多Activity和Fragment都需要重复上面EventBus的操作,onCreate
和onDestroy
中重复的操作也是很头疼的,所以考虑把register
和unregister
这两个操作封装到BaseActivity和BaseFragment中,接下来主要看BaseActivity中的封装。
2、初次封装
public abstract class BaseAppCompatActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isBindEventBus()) {
EventBus.getDefault().register(this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (isBindEventBus()) {
EventBus.getDefault().unregister(this);
}
}
/**
* 当前Activity是否需要绑定EventBus
* @return
*/
protected abstract boolean isBindEventBus();
}
public class MainActivity extends BaseAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected boolean isBindEventBus() {
return true;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
}
}
初次封装完成,成功将register
和unregister
这两个操作封装到了BaseAppCompatActivity中,这下MainActivity解脱了。但是随之而来的是增加了新的抽象方法isBindEventBus
,所有继承BaseAppCompatActivity的Activity都得重写这个方法,这样带来了新的问题,有的Activity并不需要绑定EventBus,但是因为继承关系导致必须重写这个方法并返回false。不管从架构还是维护角度看这都不是最好的解决方案,所以还得摸索新的思路,这时候想到了注解。
3、再次封装
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindEventBus {
}
public abstract class BaseAppCompatActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (this.getClass().isAnnotationPresent(BindEventBus.class)) {
EventBus.getDefault().register(this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (this.getClass().isAnnotationPresent(BindEventBus.class)) {
EventBus.getDefault().unregister(this);
}
}
}
@BindEventBus
public class MainActivity extends BaseAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
}
}
这个注解的思路是从ButterKnife
来的,给需要绑定EventBus的Activity加上类注解BindEventBus
,这样在BaseAppCompatActivity中判断当前子类上是否有该注解,有则register
和unregister
。这时候再看,代码明显干净了,风格也更Java了。经过测试,EventBus收发消息没问题,相关代码都在 android-blog-samples。
关于Java注解的原理和用法网上的学习资料很多,这里留一个慕课网的视频:全面解析Java注解。
~ the end ~