1简介
EventBus是一种为了优化Android组件之间事件传递的解耦工具,通过发布/订阅事件总线来实现事件在不同组件之间的事件传递。EventBus可以减少接口回调使用,避免大量内部类的产生,从而降低耦合。
2EventBus的使用
2.1集成EventBus
添加依赖
compile 'org.greenrobot:eventbus:3.0.0'
如果不使用加速模式这样就够了。
如果使用加速模式还需做一下配置:
添加插件
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
启用插件
apply plugin: 'com.neenbedankt.android-apt'
apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
apt {
arguments {
eventBusIndex "com.bandeng.MyEventBusIndex"
}
}
然后在Rebuild Project。最后需要在Application的onCreate里添加以下代码:
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
以上EventBus就能正常使用了。
2.2EventBus简单使用
现在做的是从一个fragment向另一个fragment传值:
这是MainActivity的布局,就放了两个fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent">
<fragment
android:layout_width="0dp"
android:layout_weight="1"
android:id="@+id/sendfragment"
android:name="demo.zouyan.com.eventbusdemo.SnedFragment"
android:layout_height="match_parent"/>
<View
android:layout_width="1dp"
android:background="@android:color/background_dark"
android:layout_height="match_parent"/>
<fragment
android:layout_width="0dp"
android:id="@+id/reciverfragment"
android:layout_weight="1"
android:name="demo.zouyan.com.eventbusdemo.ReceiverFragment"
android:layout_height="match_parent"/>
</LinearLayout>
新建个实体类:
public class MessageEvent {
private String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
下面是SnedFragment代码:
public class SnedFragment extends Fragment {
public SnedFragment() {
}
private int count = 0;
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sned, container, false);
view.findViewById(R.id.btn_send_lv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
count++;
//这一句就是发送数据
EventBus.getDefault().post(new MessageEvent("第"+count+"条信息");
}
});
return view;
}
}
下面是ReceiverFragment代码:
public class ReceiverFragment extends Fragment {
private ListView lv_receiver;
private List<String> list;
private ArrayAdapter adapter;
public ReceiverFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_receiver, container, false);
lv_receiver = view.findViewById(R.id.lv_receiver);
list = new ArrayList<>();
adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, list);
lv_receiver.setAdapter(adapter);
//注册EventBus
EventBus.getDefault().register(this);
return view;
}
//订阅信息,post过来的信息将在这里被接收
@Subscribe
public void getMessage(MessageEvent event) {
list.add(event.getMessage());
adapter.notifyDataSetChanged();
}
@Override
public void onStop() {
super.onStop();
//取消注册EventBus
EventBus.getDefault().unregister(this);
}
}
上面是运行结果的动图。
2.3EventBus向不同方法发消息
EventBus向不同的方法发送信息的话只要使用不同的event类就行。例如:
在上面的代码的基础上修改,新建了一个ToastEvent类,内容与上文的MessageEvent一致,然后在SendFragment添加一个button:
view.findViewById(R.id.btn_send_toast).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new ToastEvent("第"+count+"条信息");
}
});
在ReceiverFragment里添加一个方法用于接收ToastEvent
@Subscribe
public void getMessage2(ToastEvent event) {
Toast.makeText(getActivity(), event.getMsg(), Toast.LENGTH_SHORT).show();
}
下面是运行结果
2.4EventBus事件的优先级与事件拦截
优先级priority 的默认为0,从0开始越大越先接收。事件拦截与广播的拦截类似,只要在优先级到高的接收方法中消费掉event,优先级低的事件相同的接收方法就不会接收到event。下面是例子。
还是基于上面代码,在ReceiverFragment中添加三个方法接收MessageEvent事件,并在priority为2的方法中消费event。
@Subscribe(priority = 1)
public void getMessage_1(MessageEvent event) {
list.add(event.getMessage());
adapter.notifyDataSetChanged();
}
@Subscribe(priority = 2)
public void getMessage_2(MessageEvent event) {
EventBus.getDefault().cancelEventDelivery(event);
list.add(event.getMessage());
adapter.notifyDataSetChanged();
}
@Subscribe(priority = 3)
public void getMessage_3(MessageEvent event) {
list.add(event.getMessage());
adapter.notifyDataSetChanged();
}
下面是运行结果,可以看到在listview中只添加了2项数据,说明priority为2的方法拦截掉了event,导致
priority为1与之前优先级默认为的0方法都接不到消息。
2.5EventBus粘性事件
EventBus与BroadCast类似有粘性,即可以先发送event,在注册EventBus也能接收到event,但是只能接收到最新的一个event。
EventBus的粘性的属性是sticty默认值false,将其设置成true就能接收粘性事件了。以下是个例子。
还是基于上面的代码,新建一个SecondActivity,只有一个text为SecondActivity的TextView。
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
//设置为可接收粘性事件
@Subscribe(sticky = true)
public void receiver(StickyMessgae msg){
TextView tv = (TextView) findViewById(R.id.tv_text);
tv.setText(msg.getMsg());
}
}
在SendFragment中添加两个Button,一个用于发送粘性事件,一个为启动SecondActivity。
下面一句是发送粘性事件
下面一句是发送粘性事件
EventBus.getDefault().postSticky(new StickyMessgae("第"+count+"条信息");
运行结果如下:
可以看到SecondActivity中的TextvView的text变为了上一个Activity发送过来的内容。
3总结
EventBus我主要是用来代替部分原来使用Handler、BroadcastReceiver、startActivityForResult进行通信的地方。