美文网首页1-Android开发知识
Android项目实战 EventBus的封装

Android项目实战 EventBus的封装

作者: Androidad | 来源:发表于2017-05-26 14:11 被阅读1375次

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的操作,onCreateonDestroy中重复的操作也是很头疼的,所以考虑把registerunregister这两个操作封装到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) {

    }
    
}

初次封装完成,成功将registerunregister这两个操作封装到了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中判断当前子类上是否有该注解,有则registerunregister。这时候再看,代码明显干净了,风格也更Java了。经过测试,EventBus收发消息没问题,相关代码都在 android-blog-samples

关于Java注解的原理和用法网上的学习资料很多,这里留一个慕课网的视频:全面解析Java注解

~ the end ~

相关文章

网友评论

  • Hankkinn:运行时注解?不考虑一下性能问题么?
  • 冉桓彬:我在你的基础上做了个扩展, 因为有的Activity的register可能需要在onResume里面执行;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    EventBusManager.resigter(this, ActivityLifeCycleEngine.ONCREATE);
    }

    @Override
    protected void onResume() {
    super.onResume();
    EventBusManager.resigter(this, ActivityLifeCycleEngine.ONONRESUME);
    }

    @Override
    protected void onStart() {
    super.onStart();
    EventBusManager.resigter(this, ActivityLifeCycleEngine.ONSTART);
    }

    public class EventBusManager {
    public static void register(Object obj) {
    if (!isRegistered(obj)) {
    EventBus.getDefault().register(obj);
    }
    }

    public static void unregister(Object obj) {
    if (!isRegistered(obj)) {
    EventBus.getDefault().unregister(obj);
    }
    }

    public static boolean isRegistered(Object obj) {
    return EventBus.getDefault().isRegistered(obj);
    }

    public static void resigter(Object obj, ActivityLifeCycleEngine activityLifeCycleEngine) {
    if (obj.getClass().isAnnotationPresent(BindEventBus.class)) {
    if (isRegistered(obj)) return;
    BindEventBus annotation = obj.getClass().getAnnotation(BindEventBus.class);
    if (annotation == null) return;
    ActivityLifeCycleEngine lifecycle = annotation.lifecycle();
    if (lifecycle == activityLifeCycleEngine) {
    register(obj);
    }
    }
    }
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface BindEventBus {
    ActivityLifeCycleEngine lifecycle() default ActivityLifeCycleEngine.ONCREATE;
    }

    public enum ActivityLifeCycleEngine {
    ONCREATE,
    ONSTART,
    ONONRESUME;
    }
  • 全是干货:很棒的思路
  • e9d1e83afb99:做的很棒
  • a46aa4d1b3f8::smile: 不错,很有想法

本文标题:Android项目实战 EventBus的封装

本文链接:https://www.haomeiwen.com/subject/evgtfxtx.html