Android EventBus3.0的使用

Android EventBus3.0的使用

1.前言

EventBus是一款轻量级的事件发布/订阅框架。主要是用于各个组件或是线程之间的数据传递。将事件的发送者和接受者分离开来,避免了复杂的和易错的依赖关系。既然听起来这么美好,那么我们就开始使用它吧。
第一件事永远别忘了,就是配置 build.gradle

compile 'org.greenrobot:eventbus:3.0.0'

2.基本使用及示例

由于EventBus采用了观察者的设计模式,如果直接看使用方法有点不太好理解,建议可以先去了解一下观察者模式。那么,就直接进入正题吧。

① 在接收事件的地方进行注册。

EventBus.getDefault().register(this);

② 创建一个EventBus消息类,用于存放一些数据,有些类似我们JavaBean类。

public class MessageEvent {
    private String message;
    public MessageEvent(String message) {
        this.message = message;
    }
}

③ Post发送事件

EventBus.getDefault().post(messageEvent);

④ 接收事件,方法名可进行自定义,但是注解 @Subscribe 必须有,并且权限必须为public。

@Subscribe
public void abc(MessageEvent messageEvent) {
    ...
}

⑤ 取消注册,有注册就必须有解注册,并且我们一般在 onDestroy 里执行取消注册的操作。

EventBus.getDefault().unregister(this);

那么,我们大致了解了EventBus的使用流程之后,就用一个小示例来加深一下理解吧。这里我就使用Activity与Fragment的通信作为例子吧。

public class FragmentEvent {
    private String text;
    FragmentEvent(String text){
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

同样是先创建消息类,其他代码比较简单,就只贴上重要的部分吧。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button button_post;
    private EditText et;
    private EVFragment fragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
        button_post = (Button) findViewById(R.id.button_post);
        et = (EditText) findViewById(R.id.et);
        button_post.setOnClickListener(this);
        fragment = new EVFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.content, fragment);
        transaction.commit();
    }

    @Override
    public void onClick(View v) {
        String message = et.getText().toString();
        if(TextUtils.isEmpty(message)) {
            message = "没输入哦!!";
        }
        EventBus.getDefault().post(new FragmentEvent(message));
    }

    @Subscribe
    public void onFragmentEvent(FragmentEvent event) {
        fragment.setTv(event.getText());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

应该不是很难,就不废话了,直接来看下结果吧。

这里写图片描述

3.线程模型

EventBus有四种线程模型,它们分别是POSTING、MAIN、BACKGROUND、ASYNC。在处理事件的函数中必须指定一个线程模型,那么,为什么上面的实例中没有指定呢?是因为默认的情况下,指定的是POSTING。可以一起来看下它们四个到底是什么含义。了解之前请记住一点,主线程不能执行耗时操作,不能在子线程中更新UI

① POSTING:发送和接收事件在同一线程中,并且避免执行耗时操作。

② MAIN:无论发送事件在哪个线程,都会在UI主线程中接收事件,同样不能执行耗时操作。

③ BACKGROUND:事件在UI主线程中发送,在新线程中接收;事件在子线程中发送,则在该线程中接收。当然,不能进行UI的更新。

④ ASYNC:无论发送事件在哪个线程,都会在新建的线程中接收事件。同样不能进行UI的更新。

文字描述可能有点看的有些混乱,那么就做个表方便记忆。

线程模型主线程中发送事件子线程中发送事件
POSTING主线程子线程
MAIN主线程主线程
BACKGROUND新子线程子线程
ASYNC新子线程新子线程

当然,我就拿一个线程模型ASYNC出来写个小例子,其余的大家可以自己尝试下。

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.button_main:
            Log.i("MAIN_POST", Thread.currentThread().getName());
            EventBus.getDefault().post(new MessageEvent(""));
            break;
        case R.id.button_thread:
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Log.i("THREAD_POST", Thread.currentThread().getName());
                    EventBus.getDefault().post(new MessageEvent(""));
                }
            }).start();
            break;
    }
}

@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessageEvent(MessageEvent event) {
    Log.i("ASYNC", Thread.currentThread().getName());
}

代码还是比较好理解的,直接来看结果吧。

这里写图片描述

可以看到无论事件是从主线程还是子线程中发出来的,都是新开了一个线程来处理事件,这也就论证了上面的结论。

4.黏性事件

黏性事件的用法上与普通的很类似,区别在于,一要将sticky的值设为true,二是使用 postSticky() 方法来发送事件。同样它也有两个特点,请记住,第一个是在发送事件之后再订阅也能收到该事件,第二个是只能接收到最近的一条信息
口说无凭,还是用个例子来验证下。

@Override
public void onClick(View v) {
    EventBus.getDefault().unregister(this);

    for(int i = 0; i < 5; i++) {
        EventBus.getDefault().postSticky(new FragmentEvent(i + ""));
    }

    EventBus.getDefault().register(MainActivity.this);
}

@Subscribe(sticky = true)
public void onFragmentEvent(FragmentEvent event) {
    Log.e("RESULT", event.getText());
}

再来一起看下结果。

这里写图片描述

可以清楚的看到,总共发送了5次黏性事件,都显示没有订阅者,而发送完之后再进行注册,收到了最后一次发送的消息。

5.优先级

如果考虑到要使用优先级,那么只需要将priority的值进行设置就行了,默认情况下是为0的。priority的值越大,优先级也就越高,也就意味着最先收到发布的事件。当然,优先级的对比也是有前提的,就是必须为同一线程模型的情况下。同样,一个小例子就能说明这一切。

@Override
public void onClick(View v) {
    EventBus.getDefault().post(new FragmentEvent("priorityPK"));
}

@Subscribe(threadMode = ThreadMode.MAIN, priority = 1)
public void onFragmentEvent(FragmentEvent event) {
    Log.e("PRIORITY1", event.getText());
}

@Subscribe(threadMode = ThreadMode.MAIN, priority = 100)
public void onFEvent(FragmentEvent event) {
    Log.e("PRIORITY100", event.getText());
}

由于代码比较简单,就直接看结果了。

这里写图片描述

6.索引配置

如果一定要使用EventBus3.0的话,建议还是进行以下配置,这样效率会比较高。
首先,在Project下的build.gradle文件中添加:

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

这里写图片描述

接着,在app下的build.gradle文件中添加:

apply plugin: 'com.neenbedankt.android-apt'
apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
apt {
    arguments {
        eventBusIndex "com.lc.MyEBIndex"
    }
}

这里写图片描述

这里写图片描述

配置完后进行Rebuild,会生成如图的一个文件,该文件也就是上面配置的,可以自行命名。

这里写图片描述

最后呢,将生成的索引给默认的EventBus对象进行设置就行了。

apt {
    arguments {
        eventBusIndex "com.lc.MyEBIndex"
    }
}

那么,EventBus就学习完了,可以睡觉了。

7.总结

略!!!


参考:

EventBus使用详解
EventBus3.0 深入了解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值