EventBus 3.0用法解析
前言:为什么要使用EventBus?
EventBus在Android领域上充当优化发布/订阅事件总线的角色。简化了应用程序内各组件间、组件与后台线程间的通信。优点是开销小,代码更优雅,使用更便捷,以及将发送者和接收者解耦。不同的Activity之间传递数据实现起来还不是那么麻烦,但是在碎片(fragment)中,就显得不是那么灵活了,我们一般会使用广播来处理这些,但是广播的效率其实并不高的,传递的实体类是需要实现序列化(Serializable)的,所以成本比较高。于是就有了EventBus代替了广播。1.EventBus基本使用
依赖导入:
//EventBus(Android 事件总线 )
implementation 'org.greenrobot:eventbus:3.1.1'
1.创建一个事件类:
public class MessageEvent {
...
}
2.订阅事件:
EventBus.getDefault().register(this);
3.发送事件:
EventBus.getDefault().post(MessageEvent);
4.处理事件:注解+模式
@Subscribe(threadMode = ThreadMode.MAIN)
public void xxxx (MessageEvent event) {
...
}
补充:这里要注意的是,方法名称可以任意起名,ThreadMode默认是POSTING ,在这里指定为MAIN。
5.取消事件订阅:
EventBus.getDefault().unregister(this);
6.在MainActivity中:(注册和取消订阅事件)
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import domain.MessageEvent;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import butterknife.BindView;
import butterknife.ButterKnife;
public class TestActivity extends AppCompatActivity {
@BindView(R.id.sm1_tv)
TextView sm1Tv;
@BindView(R.id.sm1_btn)
Button sm1Btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ButterKnife.bind(this);
EventBus.getDefault().register(this);
sm1Btn.setOnClickListener(v -> {
startActivity(new Intent(TestActivity.this,A1_Sec.class));
});
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
事件订阅者处理事件:
@Subscribe(threadMode = ThreadMode.MAIN)
public void recyMsg(MessageEvent event) {
sm1Tv.setText(event.getMessage());
}
在SecondActivity中 :(事件发布者发布事件)
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import domain.MessageEvent;
import org.greenrobot.eventbus.EventBus;
import butterknife.BindView;
import butterknife.ButterKnife;
public class SecendActivityextends AppCompatActivity {
@BindView(R.id.a1_sec_btn)
Button a1SecBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a1__sec);
ButterKnife.bind(this);
a1SecBtn.setOnClickListener(v -> {
EventBus.getDefault().post(new MessageEvent("我是SecendActivity发送的消息"));
finish();
});
}
}
点击跳转到SecondActivity — > 发送消息 ----> 回显Activity (效果如下)
补充:ThreadMode.MAIN模式在Activity未被创建的之前,如果已经发送消息了,在创建注册的时候会抛异常:
D/EventBus: No subscribers registered for event class XXX
org.greenrobot.eventbus.EventBusException:
Subscriber class com.lenovo.manufacture.XXX(注册者) already registered to event class XXX(事件类)
我们可以利用EventBus粘性事件特性来解决这个问题
2.EventBus粘性事件
概念:在发送者发送消息之前事件未被订阅
模拟场景其实很简单,修改之前的代码:
MainActivity:(添加一个按钮用来注册事件 [sm1RegBtn] )
sm1RegBtn.setOnClickListener(v -> {
EventBus.getDefault().register(MainActivity.this);
});
}
订阅粘性事件的处理:
@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
public void recyMsg(MessageEvent event) {
sm1Tv.setText(event.getMessage());
}
发送粘性事件
a1SecBtn.setOnClickListener(v -> {
EventBus.getDefault().postSticky(new MessageEvent("我是SecendActivity发送的粘性事件消息"));
finish();
});
**点击跳转到SecondActivity — > 发送消息 ----> 回显Activity **
我们看到MainActivity数据是没有显示的,这是因为我们还没有订阅事件,接着点击粘性事件注册
回显Activity --> 点击粘性事件注册(大工告成)
好了这里就是EventBus事件总线的简单使用了