1. 程式人生 > >Android EventBus框架(一)之使用詳細介紹

Android EventBus框架(一)之使用詳細介紹

研發DEMO背景

最近開發專案遇到一個情景,就是在APP主頁MainActivity展示列表,有收藏功能,但是點收藏的時候,需要當前使用者是已經登入身份,因此當用戶點選列表item收藏按鈕時,如果使用者沒有登入,便會跳轉到APP的登入頁(LoginActivity),此時如果使用者之前並沒有使用者名稱/密碼,又會點選此頁面的立即註冊,跳轉到註冊介面(RegistActivity),那麼當在註冊介面使用者註冊成功的時候,我們需要三個操作:

  1. 關閉註冊介面
  2. 關閉登入介面
  3. 回到主頁,並修改主頁使用者的登入狀態

    操作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更好  
3is fast //更快4is tiny (~50k jar) //jar包小5is 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背後的事件釋出–訂閱的原理—