Android EventBus 基本使用

Android EventBus 基本使用

1、EventBus简介

地址: EventBus

EventBus是一种用于Android的事件发布-订阅总线,由GreenRobot开发,它简化了应用程序与各个组件之间通信的复杂度,尤其是碎片之间通信的问题,可以避免由于使用广播带来的不便.

1.1 三个角色

  1. Event 事件,它可以是任何类型,EventBus会根据事件类型进行全局通知;
  2. Subscriber 事件订阅者,在EventBus 3.0之前我们必须定义以OnEvent开头的那几个方法: onEventOnEventMainThreadOnEventBackgroundThreadOnEventAsync ,而在3.0之后事件处理方法名可以随意取,不过需要加上注解 @Subcribe,并且指定线程模型,默认为POSTING;
  3. Publisher 事件发布者,可以在任意线程里发布事件,一般情况下使用**Event.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)**方法即可;

1.2 四种线程模型

EventBus 3.0有四种线程模型,分别是:

  • POSTING 默认,表示事件发布跟事件处理函数的线程在同一个线程.
  • MAIN 表示事件处理函数的线程在主线程(UI线程),因此不能在此做耗时操作.
  • BACKGROUP 表示事件处理函数的线程在后台线程,因此不能进行UI操作.如果发布事件线程是主线程(UI线程),那么事件处理函数会开启一个后台线程,如果发布事件线程在后台线程,那么处理事件函数就使用该线程;
  • ASYNC 表示无论发布事件的线程是哪一个,事件处理函数始终都会开启一个新的子线程运行,但是同样不能进行UI操作;

2、EventBus使用

2.1 引入依赖

在使用之前要先引入依赖:

implementation 'org.greenrobot:eventbus:3.2.0'

如果有开启代码混淆需要添加代码混淆

-keepattributes *Annotation*
-keepclassmembers class * {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
 
# And if you use AsyncExecutor:
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

2.2 定义事件

我们定义一个事件的封装对象,在程序内部就使用该对象作为通信的信息:

public class ToastEvent {

    public String toastMsg;

    public ToastEvent getInstance(String toastMsg) {
        return new ToastEvent(toastMsg);
    }

    private ToastEvent(String toastMsg) {
        this.toastMsg = toastMsg;
    }
}

2.3 发布事件

定义一个Activity:

public class EventBusActivity extends AppCompatActivity {

    @BindView(R.id.txt_register)
    TextView textView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_eventbus);
        ButterKnife.bind(this);

    }

    @OnClick(R.id.txt_register)
    public void registerClick() {
        EventBus.getDefault().register(this);
    }

    @OnClick(R.id.txt_next)
    public void nextActivity() {
        Intent intent = new Intent(this, EventBusActivity1.class);
        startActivity(intent);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onToast(ToastEvent event) {
        Toast.makeText(this, event.toastMsg, Toast.LENGTH_LONG).show();
        textView.setText(event.toastMsg);
    }

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

这里我们按下注册按钮去注册EventBus,然后按下另外一个按钮去下一个Activity,在第二个Activity的发送按钮点击之后发布事件,在上面的Activity中,我们会添加一个监听方法, 即onToast 这里我们需要为其加入注解Subscribe 并指定线程模型为 MAIN 主线程,最后在 onDestroy方法中取消注册;

下面是另外一个Activity的定义,在这个Activity中,当按下发送按钮的时候发布事件并关闭当前页面回到之前Activity,可以看到之前的注册按钮的文案已经修改成了“I am Toast”,并Toast了“I am Toast”;

public class EventBusActivity1 extends AppCompatActivity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_eventbus_1);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.txt_send_toast)
    public void sendToast() {
        EventBus.getDefault().post(ToastEvent.getInstance("I am Toast"));
        finish();
    }
}

2.4 黏性事件

所谓的黏性事件,就是指发送了该事件之后再订阅者依然能够接收事件.使用黏性事件的时候有两个地方需要做些修改,一个是订阅事件的地方,这里在先打开的Activity中注册监听黏性事件:

    @Subscribe(threadMode = ThreadMode.MAIN ,sticky =  true)
    public void onStickyToast(ToastEvent event){
        Toast.makeText(this, event.toastMsg, Toast.LENGTH_LONG).show();
        textView.setText(event.toastMsg);
    }

另外一个是发布事件的地方,这里我们的Activity中发布黏性事件,即调用EventBuspostSticky 方法来发布事件:

    private void pushStickyEvent() {
        EventBus.getDefault().postSticky(ToastEvent.getInstance("I am Sticky Event"));
    }

按照上面的模式,我们现在第一个Activity中打开了第二个Activity,然后发送黏性事件,回到第一个Activity中去注册EventBus.当按下注册按钮之后,立即触发上面的订阅方法从而获得黏性事件.

2.5优先级

Subscriber注解中总共有三个参数,上面我们介绍使用了两个,现在来说第三个,那就是优先级(priority),它用来指定订阅方法的优先级,是一个整数类型的值,默认为0,值越大代表优先级越高,在某个事件被发布出来的时候,优先级高的订阅方法会首先接收到事件.

为了对优先级进行测试,我们对上面的代码进行修改,我们使用一个布尔类型的变量来判断是否应该取消事件的分发,我们在优先级较高的方法中通过该布尔值进行判断,如果为true就停止该事件分发,从而通过低优先级订阅方法无法获取到事件来证明优先级较高的订阅方法率先获得事件.

需要注意几个点:

  1. 只有当两个订阅方法使用相同ThreadMode 参数的时候,他们的优先级才会与Priority指定的值一样.
  2. 只有当某个订阅方法的ThreadMode参数为POSTING它才能停止该事件的继续分发.

所以,根据以上的内容,我们对代码进行修改:

    @OnClick(R.id.txt_stop_delivery)
    public void setStopDelivery() {
        stopDelivery = true;
    }


    @Subscribe(threadMode = ThreadMode.POSTING, priority = 0)
    public void onToast(ToastEvent event) {
        Toast.makeText(this, event.toastMsg, Toast.LENGTH_LONG).show();
        textView.setText(event.toastMsg);
    }

    // 订阅方法,需要与上面的方法的threadMode一致,并且优先级略高
    @Subscribe(threadMode = ThreadMode.POSTING, sticky = true, priority = 1)
    public void onToastPriority(ToastEvent event) {
        Toast.makeText(this, event.toastMsg + "Sticky Event", Toast.LENGTH_LONG).show();
        textView.setText(event.toastMsg + "Sticky Event");
        //停止事件继续分发
        if (stopDelivery) {
            EventBus.getDefault().cancelEventDelivery(event);
        }
    }

我们在之前的代码上新增一个停止分发的按钮,用来将 stopDelivery 设置为 true ,该字段之后会被用来判断是否终止事件的继续分发,因为我们需要在代码中停止事件的继续分发,所以我们将上面的两个订阅方法的加粗ThreadMode值都设置为ThreadMode.POSTING;

按照上面的测试方式,首先在我们当前Activity注册监听,然后跳转到另外一个Activity,发布事件并返回,第一次的时候这里的两个订阅方法都会被触发;然后,我们按下停止分发按钮,并再次进入下一个Activity,发布事件返回,此时,只有优先级高的方法获得到了事件并终止了该事件继续分发.

总结:

上面的内容是 EventBus 的基本使用,更多请关注 EventBus

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值