简述
EventBus是一款针对Android优化的发布/订阅事件总线
简化了应用程序内各组件间、组件与后台线程间的通信。优点是开销小,代码更优雅,以及将发送者和接收者解耦。如果Activity和Activity进行交互还好说,如果Fragment和Fragment进行交互着实令人头疼,我们会使用广播来处理,但是使用广播稍显麻烦并且效率也不高,如果传递的数据是实体类需要序列化,那么很显然成本会有点高。今天我们就来学习下EventBus3.0的使用方法。
1.EventBus概述
EventBus的三要素
EventBus有三个主要的元素需要我们先了解一下:
● Event:事件,可以是任意类型的对象。
● Subscriber:事件订阅者,在EventBus3.0之前消息处理的方法只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,他们分别代表四种线程模型。而在EventBus3.0之后,事件处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为POSTING),四种线程模型下面会讲到。
● Publisher:事件发布者,可以在任意线程任意位置发送事件,直接调用EventBus的post(Object)方法。可以自己实例化EventBus对象,但一般使用EventBus.getDefault()就好了,根据post函数参数的类型,会自动调用订阅相应类型事件的函数。
EventBus的四种ThreadMode(线程模型)
EventBus3.0有以下四种ThreadMode:
● POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
● MAIN:
事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。
● BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
● ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。
2.EventBus基本用法实现思路
EventBus使用起来很简单,分为五个步骤:
假如有 两个页面,A和B,A是要接收事件的,B是发送事件的,
1.自定义一个事件类
public class MessageEvent {
...
}
2.在需要订阅事件的地方注册事件 它就是A页面
EventBus.getDefault().register(this);
3.发送事件 这个就是B页面要发送值得页面
EventBus.getDefault().post(messageEvent);
4.处理事件 这个要接收值的地方也是A页面
@Subscribe(threadMode = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent) {
...
}
前面我们说过,消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为POSTING)。
5.取消事件订阅 它也是A页面
EventBus.getDefault().unregister(this);
也可以这么理解相当于onActivityResult
3.EventBus3.0粘性事件
除了普通事件外,EventBus还支持发送黏性事件,就是在发送事件之后再订阅该事件也能收到该事件,跟黏性广播类似
它和普通事件的区别就是这订阅的地方了还有一个发送的地方可以和上对比下
@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
//事件发布者发布事件
EventBus.getDefault().postSticky(new UserBean(username,password));
1.添加依赖库
compile 'org.greenrobot:eventbus:3.0.0'
2.创建传递消息类对象
缺点就是没次使用都要创建对象类
public class UserBean {
private String uname;
private String pswd;
public UserBean(String uname, String pswd) {
this.uname = uname;
this.pswd = pswd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPswd() {
return pswd;
}
public void setPswd(String pswd) {
this.pswd = pswd;
}
}
3.发布者发布事件
//发布者发布事件
public class MainActivity extends AppCompatActivity {
private EditText uname,pswd;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uname=(EditText) findViewById(R.id.uname);
pswd=(EditText) findViewById(R.id.pswd);
button=(Button) findViewById(R.id.login);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = uname.getText().toString();
String password = pswd.getText().toString();
//事件发布者发布事件
EventBus.getDefault().postSticky(new UserBean(username,password));
finish();
//跳转页面
startActivity(new Intent(MainActivity.this,SucceedActivity.class));
}
});
}
}
4.事件接受值得Activity
public class SucceedActivity extends AppCompatActivity {
private TextView textData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_succeed);
textData=(TextView) findViewById(R.id.textData);
//注册事件
EventBus.getDefault().register(this);
}
/**
* 订阅者处理粘性事件
* @param userBean 接手过来的实体类
*/
@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
public void ononMoonStickyEvent(UserBean userBean){
textData.setText(userBean.getUname()+userBean.getPswd());
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册事件
EventBus.getDefault().unregister(this);
}
}
5.布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.bwei.eventbusdemo.MainActivity">
<EditText
android:id="@+id/uname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="70dp"
android:ems="10"
android:inputType="textPersonName"
/>
<EditText
android:id="@+id/pswd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/uname"
android:layout_alignRight="@+id/uname"
android:layout_below="@+id/uname"
android:layout_marginTop="37dp"
android:ems="10"
android:inputType="textPersonName"
/>
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/pswd"
android:layout_centerHorizontal="true"
android:layout_marginTop="51dp"
android:text="登录" />
</RelativeLayout>