EventBus使用

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:

    
    
    


   新建个实体类:
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 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);
    }
}
EventBus使用_第1张图片

上面是运行结果的动图。

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();
    }
下面是运行结果
EventBus使用_第2张图片

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方法都接不到消息。

EventBus使用_第3张图片

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+"条信息");

运行结果如下:
EventBus使用_第4张图片

可以看到SecondActivity中的TextvView的text变为了上一个Activity发送过来的内容。

3总结

EventBus我主要是用来代替部分原来使用Handler、BroadcastReceiver、startActivityForResult进行通信的地方。

你可能感兴趣的:(Android,EventBus)