Android EventBus框架(一)之使用詳細介紹
阿新 • • 發佈:2019-02-10
研發DEMO背景
最近開發專案遇到一個情景,就是在APP主頁MainActivity展示列表,有收藏功能,但是點收藏的時候,需要當前使用者是已經登入身份,因此當用戶點選列表item收藏按鈕時,如果使用者沒有登入,便會跳轉到APP的登入頁(LoginActivity),此時如果使用者之前並沒有使用者名稱/密碼,又會點選此頁面的立即註冊,跳轉到註冊介面(RegistActivity),那麼當在註冊介面使用者註冊成功的時候,我們需要三個操作:
- 關閉註冊介面
- 關閉登入介面
回到主頁,並修改主頁使用者的登入狀態
操作1直接finish()即可,要實現操作2和3的話,我們平常一般會用到傳送廣播和接收廣播來實現,這裡其實可以用EventBus來實現。
EventBus框架介紹
官方的介紹特點如下:
(1)simplifies the communication between components decouples event senders and receivers //釋出--訂閱關係
(2)performs well with Activities, Fragments, and background threads avoids complex and error-prone dependencies and life cycle issues makes your code simpler //效能比Handler更好
(3)is fast //更快
(4)is tiny (~50k jar) //jar包小
(5)is proven in practice by apps with 100,000,000+ installs //使用者廣泛
EventBus是一款針對Android優化的釋出/訂閱事件匯流排。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,執行緒之間傳遞訊息.優點是開銷小,程式碼更優雅,以及將傳送者和接收者解耦。
EventBus框架中涉及四個成分
訂閱者,釋出者,訂閱事件,事件匯流排
它們的關係可以用官方的圖表示:
訂閱者可以訂閱多個事件,傳送者可以釋出任何事件,釋出者同時也可以是訂閱者。
如何使用
官方給到四個步驟(EventBus in 4 steps):
(1)Define events://定義事件
public class MessageEvent { /* Additional fields if needed */ }
(2)Prepare subscribers//註冊訂閱者
Register your subscriber (in your onCreate or in a constructor):
eventBus.register(this);
(3)Declare your subscribing method://訂閱事件的動作
@Subscribe
public void onEvent(AnyEventType event) {/* Do something */};
(4)Post events://釋出者傳送事件
eventBus.post(event);
在專案中,最主要用到的EventBus的方法有:
EventBus.getDefault().register(this);//訂閱事件
EventBus.getDefault().post(object);//釋出事件
EventBus.getDefault().unregister(this);//取消訂閱
onEvent:使用onEvent作為訂閱函式,那麼該事件在哪個執行緒釋出出來的,onEvent就會在這個執行緒中執行,也就是說釋出事件和接收事件執行緒在同一個執行緒。
onEventMainThread:無論事件在哪個執行緒釋出出來的,始終在UI執行緒中執行訂閱事件的操作。
onEventBackground:無論事件在哪個執行緒釋出出來的,始終在工作執行緒中執行訂閱事件的操作。
onEventAsync:使用這個函式作為訂閱函式,那麼無論事件在哪個執行緒釋出,都會建立新的子執行緒在執行onEventAsync.
下面結合上文的具體情境來具體實現
DEMO的專案目錄如下:
首先在build.gradle中新增依賴:
compile 'org.greenrobot:eventbus:3.0.0'
主頁MainActivity程式碼如下:
public class MainActivity extends AppCompatActivity {
private TextView tv1,tv_status;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);//在當前介面註冊一個訂閱者
tv1=(TextView)findViewById(R.id.tv);
tv_status=(TextView)findViewById(R.id.tv_status);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(intent);
}
});
}
@Subscribe //訂閱事件FirstEvent
public void onEventMainThread(LoginSuccessdEvent event){
String msg=event.getMsg();
tv_status.setText("已登入,當前賬號"+msg);//獲取事件中傳遞的引數
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);//取消註冊
}
}
登入介面LoginActivity.java:
@Subscribe //訂閱事件FirstEvent
public void onEventMainThread(LoginSuccessdEvent event){
Log.i("TAG","LoginSuccessdEvent");
LoginActivity.this.finish();//收到訂閱事件之後關閉當前介面
Toast.makeText(this, "finish", Toast.LENGTH_LONG).show();
}
在註冊介面RegistActivity:
//釋出事件
EventBus.getDefault().post(new LoginSuccessdEvent(username));
定義一個登入成功事件類LoginSuccessdEvent .java:
public class LoginSuccessdEvent {
private String msg;
public LoginSuccessdEvent(String msg) {//事件傳遞引數
this.msg = msg;
}
public String getMsg() {//取出事件引數
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
最後實現的大概狀態是:
這樣就使用EventBus完成了當註冊成功後,主介面的登入狀態的修改和登入介面的finish。當然引入第三方框架來實現並不是最好的方法,不過可以讓我們瞭解EventBus的用法,以及感興趣的話,可以深入EventBus背後的事件釋出–訂閱的原理—