EventBus学习笔记

Android开发时,常用的通信方式有以下几种:Handler、Broadcast、Intent

1. 广播
作为Android的四大组件之一,广播是重量级的,比较消耗资源,单纯的用于消息传递,大材小用。若和Android交互,用到Context或Intent的时候,广播的便捷性就凸显出来了。另外,许多系统级的事件都是通过广播来通知的,比如说网络、电量的变化,短信发送和接收的状态等。所以,如果与Android系统进行相关的通知,还是要选择广播。
2. Handler
Handler一般用于线程间通信,但事件发布者和接受者之间的耦合度太高。
3.Intent
启动Activity时,startActivityForResult()/onActivityResult()常用于传递消息,但会产生较多的状态或逻辑判断,而且Intent或Bundle传值还得检测类型,若传递的数据类型和接收的类型不一致,在编译期间无法发现,只有在运行时才会报错。

4. 给SharedPreference设置监听 OnSharedPreferenceChangeListener不被调用原理及解决方案

作为主流的解耦框架,EventBus和以上三种方式相比,其优势在于调度灵活,不依赖于Context,同时解除了Handler所带来的高耦合,同时,不用考虑切换线程,很简单地实现发布订阅功能。

缺点:使用位置较多时,出现问题后很难定位;代码可读性不好

基本使用如下:

1.注册

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        bc = findViewById(R.id.bc);
        EventBus.getDefault().register(this);//这句话要放在初始化组件(findViewById)之后,不然页面接收不到参数。
    }

2. 解注册

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

3. 发消息

EventBus.getDefault().post("aaa");

4.接收并处理消息

@Subscribe(threadMode = ThreadMode.MAIN)
public void test(String s){
    if (s.equals("aaa")){
        Toast.makeText(AtyAirMain.this,"test",Toast.LENGTH_SHORT).show();
    }
}

EventBus 3.0支持注解方式,而且支持注解中设置ThreadMode、sticky事件、优先级。如:

@Subscribe(threadMode = ThreadMode.BACKGROUND, sticky = true, priority = 100)

4.1 ThreadMode
POSTING 
Subscriber will be called directly in the same thread, which is posting the event. This is the default. Event delivery implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for simple tasks that are known to complete in a very short time without requiring the main thread. Event handlers using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.
订阅者将在发布事件的同一线程中直接调用。这是默认值。事件传递意味着最小的开销,因为它完全避免了线程切换。因此,可以短时间内完成而无需主线程的简单任务推荐该模式。使用此模式的事件处理程序必须快速返回,以避免阻塞可能是主线程的发布线程。

MAIN
On Android, subscriber will be called in Android's main thread (UI thread). If the posting thread is the main thread, subscriber methods will be called directly, blocking the posting thread. Otherwise the event is queued for delivery (non-blocking). Subscribers using this mode must return quickly to avoid blocking the main thread. If not on Android, behaves the same as {@link #POSTING}.
在Android上,订阅者将在Android的主线程(UI线程)中被调用。如果发布线程是主线程,则将直接调用订阅者方法,从而阻止发布线程。否则,事件将排队等待传递(非阻塞)。使用此模式的订阅者必须快速返回以避免阻塞主线程。如果不是在Android上,则其行为与{@link #POSTING}相同。
  
MAIN_ORDERED
On Android, subscriber will be called in Android's main thread (UI thread). Different from {@link #MAIN}, the event will always be queued for delivery. This ensures that the post call is non-blocking.
在Android上,订阅者将在Android的主线程(UI线程)中被调用。与{@link #MAIN}不同的是,该事件将始终排队等待传递。这样可以确保发布呼叫是非阻塞的。

BACKGROUND
On Android, subscriber will be called in a background thread. If posting thread is not the main thread, subscriber methods will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single background thread, that will deliver all its events sequentially. Subscribers using this mode should try to return quickly to avoid blocking the background thread. If not on Android, always uses a background thread.
在Android上,订阅者将在后台线程中被调用。如果发布线程不是主线程,则订阅者方法将直接在发布线程中调用。如果发布线程是主线程,则EventBus使用单个后台线程,该线程将按顺序传递其所有事件。使用此模式的订户应尝试快速返回以避免阻塞后台线程。如果不是在Android上,则始终使用后台线程。

ASYNC
Subscriber will be called in a separate thread. This is always independent from the posting thread and the main thread. Posting events never wait for subscriber methods using this mode. Subscriber methods should use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number of long running asynchronous subscriber methods at the same time to limit the number of concurrent threads. EventBus uses a thread pool to efficiently reuse threads from completed asynchronous subscriber notifications.
订户将在单独的线程中被调用。这始终独立于发布线程和主线程。发布事件永远不会等待使用此模式的订阅者方法。如果订阅者方法的执行可能要花费一些时间(例如,用于网络访问。避免同时触发大量长时间运行的异步订阅者方法,以限制并发线程的数量。 EventBus使用线程池来有效地重用已完成的异步订阅者通知中的线程。

2.2粘性事件
何为黏性事件呢?简单讲,就是在发送事件之后再订阅该事件也能收到该事件,这点类似粘性广播。比如A页面中EventBus先post了一个消息给B页面,但此时B页面未启动,也就是B页面中的EventBus还未注册,此时就要使用粘性事件,当B页面启动并注册了EventBus,就可接收到该消息。

EventBus.getDefault().postSticky(new TestEvent("mmm"));//A页面
//粘性事件,要设置sticky = true
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void test(TestEvent event){//B页面
    Log.d(TAG, "test: " + event.getStr());
}

此时用到了自定义事件TestEvent

public class TestEvent {
    private String str;
    public TestEvent(String str) {
        this.str = str;
    }
    public String getStr() {
        return str;
    }
}

参考:

Android消息处理:EventBus、BroadCast和Handler-优缺点比较

BroadcastReceiver和EventBus区别是什么

EventBus使用详解

EventBus

EventBus3.0中粘性事件postSticky使用

EventBus和Otto的故事

EventBus & Otto的使用和比较

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值