Android EventBus3.x的使用詳解
前言
在Android的日常開發中,我們經常會遇到程式和元件的通訊問題。
一般我們可以使用廣播,Handler等方式來處理。
但是廣播存在麻煩,效率也不高,如果傳遞的資料是實體類需要序列化,那麼很顯然成本會有點高等問題。
Hander主要用於週期性訊息傳遞,用於通訊則會造成記憶體洩漏等諸多問題。
所以今天我們要介紹使用EventBus來解決這些問題。
EventBus
GitHub開源地址:https://github.com/greenrobot/EventBus
什麼是EventBus?
EventBus是一款針對Android優化的釋出/訂閱事件匯流排。
簡化了應用程式內各元件間、元件與後臺執行緒間的通訊。
優點是開銷小,程式碼更優雅,以及將傳送者和接收者解耦。
EventBus的三個的元素
- Event:事件。可以是任意型別的物件。
- Subscriber:事件訂閱者。在EventBus3.0之前訊息處理的方法只能限定於onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,他們分別代表四種執行緒模型。而在EventBus3.0之後,事件處理的方法可以隨便取名,但是需要新增一個註解@Subscribe,並且要指定執行緒模型(預設為POSTING)。
- Publisher:事件釋出者。我們可以在任意執行緒裡釋出事件,一般情況下,使用EventBus.getDefault()就可以得到一個EventBus物件,然後再呼叫post(Object)方法即可。
EventBus的四種執行緒模型
上面三元素的時候提到過3.0之前是使用4個方法來對於四種執行緒模型,而3.0以後使用註解的方法指定執行緒模型。
- POSTING:(預設) 表示事件處理函式的執行緒跟釋出事件的執行緒在同一個執行緒。儘量避免執行耗時操作,因為它會阻塞事件的傳遞,甚至有可能會引起ANR。
- MAIN:表示事件處理函式的執行緒在主執行緒(UI)執行緒,因此在這裡不能進行耗時操作。
- BACKGROUND:表示事件處理函式的執行緒在後臺執行緒,因此不能進行UI操作。如果釋出事件的執行緒是主執行緒(UI執行緒),那麼事件處理函式將會開啟一個後臺執行緒,如果果釋出事件的執行緒是在後臺執行緒,那麼事件處理函式就使用該執行緒。
- ASYNC:表示無論事件釋出的執行緒是哪一個,事件處理函式始終會新建一個子執行緒執行,同樣不能進行UI操作。
EventBus3.0使用
Gradle引入
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
該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;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<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);
}
}
<?xml version="1.0" encoding="utf-8"?>
<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/Demo-DeMon/RxEventBus
參考
相關文章
- 詳解Android RxJava的使用AndroidRxJava
- Android shape的使用詳解Android
- 詳解Android中AsyncTask的使用Android
- Android Gson使用詳解Android
- Android Paint 使用詳解AndroidAI
- Android AsyncTask使用詳解Android
- Android webview使用詳解AndroidWebView
- Android ViewPager使用詳解AndroidViewpager
- Android shape 的詳解及使用Android
- Android BroadcastReceiver使用詳解AndroidAST
- Android AIDL使用詳解AndroidAI
- Android Support Annotations 使用詳解Android
- Android中PopupWindow使用詳解Android
- Android中AsyncTask使用詳解Android
- Android Resources 資原始檔的使用詳解Android
- Android-SharedPreferences 使用詳解Android
- Android FragmentTabHost 使用方法詳解AndroidFragment
- Android taskAffinity屬性使用詳解Android
- Android 中 HttpURLConnection 使用詳解AndroidHTTP
- Android中HttpURLConnection使用詳解AndroidHTTP
- Android Retrofit 2.5.0使用基礎詳解Android
- Android Bitmap快取池使用詳解Android快取
- Android HOOK工具Cydia Substrate使用詳解AndroidHook
- Android圖片載入的框架Fresco使用詳解Android框架
- Android藍芽使用詳解(普通藍芽)Android藍芽
- Android多種進度條使用詳解Android
- Android生命週期元件Lifecycle使用詳解Android元件
- Android圖片載入框架Fresco使用詳解Android框架
- Android除錯神器stetho使用詳解和改造Android除錯
- Android ORM 框架:GreenDao 使用詳解(基礎篇)AndroidORM框架
- Android ORM 框架:GreenDao 使用詳解(進階篇)AndroidORM框架
- Android應用中Clean架構使用詳解Android架構
- Android官方導航欄ActionBar使用詳解Android
- Android AsyncTask 詳解Android
- Android:動畫詳解Android動畫
- Android拖拽詳解Android
- Android:Service詳解Android
- Android Notification 詳解Android