在Android的日常开发中,我们经常会遇到进程和组件的通信问题。
一般我们可以使用广播,Handler等方式来处理。
但是广播存在麻烦,效率也不高,如果传递的数据是实体类需要序列化,那么很显然成本会有点高等问题。
Hander主要用于周期性消息传递,用于通信则会造成内存泄漏等诸多问题。
所以今天我们要介绍使用EventBus来解决这些问题。
GitHub开源地址:https://github.com/greenrobot/EventBus
EventBus是一款针对Android优化的发布/订阅事件总线。
简化了应用程序内各组件间、组件与后台线程间的通信。
优点是开销小,代码更优雅,以及将发送者和接收者解耦。
上面三元素的时候提到过3.0之前是使用4个方法来对于四种线程模型,而3.0以后使用注解的方法指定线程模型。
implementation 'org.greenrobot:eventbus:3.1.1'
public static class MessageEvent { /* Additional fields if needed */ }
//注册,声明订阅者
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
//销毁防止重复注册和内存泄漏
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
//处理事件,并通过注释选择指定线程模式
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
EventBus.getDefault().post(new MessageEvent());
EventBus还支持发送黏性事件,跟黏性广播类似,就是在事件发布之后再订阅该事件也能收到该事件。
一般用于接收事件的界面/进程可能没有运行,但是希望它能收到该事件。只需要设置在该界面/进程可以处理粘性事件。
在注解中添加sticky = true表明处理粘性事件。
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void onMessageEvent(MessageEvent event) {/* Do something */};
使用postSticky发布粘性事件。
EventBus.getDefault().postSticky(new MessageEvent());
该Demo演示了Activty与Fragment的通信。
public class MsgEvent {
private String msg;
public MsgEvent(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
public class EventActivity extends AppCompatActivity {
@BindView(R.id.rx)
Button rx;
@BindView(R.id.java)
Button java;
@BindView(R.id.android)
Button android;
@BindView(R.id.event_layout)
FrameLayout eventLayout;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.event_layout, new EventFragment());
transaction.commit();
}
@OnClick({R.id.rx, R.id.java, R.id.android})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.rx:
startActivity(new Intent(this, RxActivity.class));
break;
case R.id.java:
EventBus.getDefault().post(new MsgEvent("Java"));
break;
case R.id.android:
EventBus.getDefault().post(new MsgEvent("Android"));
break;
}
}
}
<LinearLayout 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"
android:orientation="vertical"
tools:context=".EventActivity">
<Button
android:id="@+id/rx"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="go to rxbus" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/java"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Java" />
<Button
android:id="@+id/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android" />
LinearLayout>
<FrameLayout
android:id="@+id/event_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
LinearLayout>
public class EventFragment extends Fragment {
@BindView(R.id.text)
TextView text;
Unbinder unbinder;
private View view;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_event, container, false);
unbinder = ButterKnife.bind(this, view);
return view;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MsgEvent event) {
text.setText(event.getMsg());
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
EventBus.getDefault().unregister(this);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="EventFragment"
android:textSize="18sp" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textSize="16sp" />
LinearLayout>
GitHub:https://github.com/MyAndroidDemo/RxEventBus
https://blog.csdn.net/itachi85/article/details/52205464