EventBus使用

来源:互联网 发布:淘宝开店在哪交保证金 编辑:程序博客网 时间:2024/06/07 08:24

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进行通信的地方。

原创粉丝点击