实例讲解EventBus的使用
2019-08-20 本文已影响6人
手指乐
EventBus介绍
EventBus用于在任意类之间通讯(包括但不限于Activity,Fragment等),它基于发布/订阅机制,只要在任意一个类中订阅了消息,就可以接受到任意一个地方发布的该消息。
下面通过一个实例来讲解EventBus的使用:
点击左侧的Fragment发布消息,右侧的Fragment订阅消息,通过日志观察消息的发布和订阅及所在的线程
- 引入EventBus
github地址:https://github.com/greenrobot/EventBus
gradle配置
implementation 'org.greenrobot:eventbus:3.1.1' - 定义消息类
消息类不一定是实体类,可以是任意的类
/**
*
* 用于消息(事件)传输的实体类
*
* Created by zhouyi on 16/7/18.
*/
public class MyEvent1 {
private String mstrMsg;
public MyEvent1(String strMsg){
mstrMsg = strMsg;
}
public String getMsg(){
return mstrMsg;
}
}
- 左侧Fragment使用不同的线程发布消息:
使用post方法发布消息即可
public class LeftFragment extends ListFragment {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
String[] strs = new String[]{"主线程消息1", "子线程消息1", "主线程消息2"};
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, strs));
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
switch (position) {
case 0:
String strMsg = "LeftFragment中主线程发送消息1";
Log.d("qf", "----主线程发送消息,线程名:"
+ Thread.currentThread().getName()
+ ",线程id"
+ Thread.currentThread().getId()
+ ",消息内容:"
+ strMsg
+ "-----");
EventBus.getDefault().post(new MyEvent1(strMsg));
break;
case 1:
new Thread(){
@Override
public void run() {
String strMsg = "LeftFragment中子线程发送消息1";
Log.d("qf", "----子线程发送消息,线程名:"
+ Thread.currentThread().getName()
+ ",线程id"
+ Thread.currentThread().getId()
+ ",消息内容:"
+ strMsg
+ "-----");
EventBus.getDefault().post(new MyEvent1(strMsg));
}
}.start();
break;
case 2:
break;
}
}
}
- 右侧的Fragment订阅消息
首先通过register方法注册
然后使用Subscribe注解来订阅消息,Subscribe注解中可以指定消息响应的线程和发布线程的关系
最后使用unregister解除注册
发布和订阅通过实体类关联,订阅的实体类跟发布一样,就可以收到消息
public class RightFragment extends Fragment {
private TextView mtvMsg;
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
/**
* 默认情况下,如果消息是主线程发送的,那么消息的响应者(接收者)
* 就在主线程运行
* 如果消息是子线程发送的,那么消息的响应者(接收者)
* 就在子线程运行
* @param event1
*/
@Subscribe
public void onEvent(MyEvent1 event1){
String strMsg = event1.getMsg();//得到消息里面传输过来的内容
Log.d("qf","onEvent接收到消息,线程名:"
+Thread.currentThread().getName()
+",线程id"
+Thread.currentThread().getId()
+",消息内容:"
+strMsg
);
//mtvMsg.setText(strMsg);
}
/**
* 不管发送方是在哪个线程发送过来的消息,接收方都在主线程里进行处理
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMain(MyEvent1 event1){
String strMsg = event1.getMsg();//得到消息里面传输过来的内容
Log.d("qf","onEventMain接收到消息,线程名:"
+Thread.currentThread().getName()
+",线程id"
+Thread.currentThread().getId()
+",消息内容:"
+strMsg
);
mtvMsg.setText(strMsg);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
EventBus.getDefault().register(this);
View view = inflater.inflate(R.layout.fragment_right, null);
mtvMsg = (TextView) view.findViewById(R.id.tv);
return view;
}
}
- 点击左侧第一个按钮,观察日志:
----主线程发送消息,线程名:main,线程id1,消息内容:LeftFragment中主线程发送消息1-----
onEvent接收到消息,线程名:main,线程id1,消息内容:LeftFragment中主线程发送消息1
onEventMain接收到消息,线程名:main,线程id1,消息内容:LeftFragment中主线程发送消息1
此时消息从主线程发出,订阅者都从主线程响应
- 点击左侧第二个按钮,观察日志:
----子线程发送消息,线程名:Thread-145,线程id145,消息内容:LeftFragment中子线程发送消息1-----
onEvent接收到消息,线程名:Thread-145,线程id145,消息内容:LeftFragment中子线程发送消息1
onEventMain接收到消息,线程名:main,线程id1,消息内容:LeftFragment中子线程发送消息1
此时消息从子线程发出,订阅消息的两个方法,第一个是默认方式,订阅线程跟发布线程一致
第二个方法在注解中使用threadMode = ThreadMode.MAIN,不管发布者在哪个线程,订阅者都在主线程响应