1. 程式人生 > >EventBus 3.0使用詳解

EventBus 3.0使用詳解

01 前言

當我們進行專案開發的時候,往往是需要應用程式的各元件、元件與後臺執行緒間進行通訊,比如在子執行緒中進行請求資料,當資料請求完畢後通過Handler或者是廣播通知UI,而兩個Fragment之家可以通過Listener進行通訊等等。當我們的專案越來越複雜,使用Intent、Handler、Broadcast進行模組間通訊、模組與後臺執行緒進行通訊時,程式碼量大,而且高度耦合。現在就讓我們來學習一下EventBus 3.0吧。

02 什麼是EventBus

  • simplifies the communication between components
    decouples event senders and receivers
    performs well with Activities, Fragments, and background threads
    avoids complex and error-prone dependencies and life cycle issues
  • makes your code simpler
  • is fast
  • is tiny (~50k jar)
  • is proven in practice by apps with 100,000,000+ installs
  • has advanced features like delivery threads, subscriber priorities, etc.

大概的意思就是:EventBus能夠簡化各元件間的通訊,讓我們的程式碼書寫變得簡單,能有效的分離事件傳送方和接收方(也就是解耦的意思),能避免複雜和容易出錯的依賴性和生命週期問題。

03 關於EventBus的概述

三要素

  • Event 事件。它可以是任意型別。
  • Subscriber 事件訂閱者。在EventBus3.0之前我們必須定義以onEvent開頭的那幾個方法,分別是onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,而在3.0之後事件處理的方法名可以隨意取,不過需要加上註解@subscribe(),並且指定執行緒模型,預設是POSTING。
  • Publisher 事件的釋出者。我們可以在任意執行緒裡釋出事件,一般情況下,使用EventBus.getDefault()就可以得到一個EventBus物件,然後再呼叫post(Object)方法即可。

四種執行緒模型

EventBus3.0有四種執行緒模型,分別是:

  • POSTING (預設) 表示事件處理函式的執行緒跟釋出事件的執行緒在同一個執行緒。
  • MAIN 表示事件處理函式的執行緒在主執行緒(UI)執行緒,因此在這裡不能進行耗時操作。
  • BACKGROUND 表示事件處理函式的執行緒在後臺執行緒,因此不能進行UI操作。如果釋出事件的執行緒是主執行緒(UI執行緒),那麼事件處理函式將會開啟一個後臺執行緒,如果果釋出事件的執行緒是在後臺執行緒,那麼事件處理函式就使用該執行緒。
  • ASYNC 表示無論事件釋出的執行緒是哪一個,事件處理函式始終會新建一個子執行緒執行,同樣不能進行UI操作。

04 EventBus的基本用法

舉個例子,我需要在一個Activity裡註冊EventBus事件,然後定義接收方法,這跟Android裡的廣播機制很像,你需要首先註冊廣播,然後需要編寫內部類,實現接收廣播,然後操作UI。所以,在EventBus中,你同樣得這麼做。

自定義一個事件類

public class MessageEvent{
    private String message;
    public  MessageEvent(String message){
        this.message=message;
    }
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
}

這裡有些同學,會有一些疑問,為什麼要建立這樣一個類,有什麼用途。其實這個類就是一個Bean類,裡面定義用來傳輸的資料的型別。

註冊事件

@Override
protected void onCreate(Bundle savedInstanceState) {           
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     EventBus.getDefault().register(this);
} 

當我們需要在Activity或者Fragment裡訂閱事件時,我們需要註冊EventBus。我們一般選擇在Activity的onCreate()方法裡去註冊EventBus,在onDestory()方法裡,去解除註冊。

解除註冊

@Override
protected void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
}

傳送事件

EventBus.getDefault().post(messageEvent);

處理事件

@Subscribe(threadMode = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent) {
    ...
}

前面我們說過,處理訊息的方法名字可以隨便取。但是需要加一個註解@Subscribe,並且要指定執行緒模型。

05 EventBus使用實戰

以上我們講了EventBus的基本用法,沒有用過的同學也不要擔心不會用,小編在這裡舉個小栗子。

第一步:新增依賴

 compile 'org.greenrobot:eventbus:3.0.0'

第二步:定義訊息事件類

public class MessageEvent{
    private String message;
    public  MessageEvent(String message){
        this.message=message;
    }
 
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
}

第三步:註冊和解除註冊

分別在FirstActivity的onCreate()方法和onDestory()方法裡,進行註冊EventBus和解除註冊。

package com.example.lenovo.testapp.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.example.lenovo.testapp.R;
import com.example.lenovo.testapp.event.MessageEvent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

/**
 * Created by ZZG on 2018/1/10.
 */

public class FirstActivity extends AppCompatActivity {
    private Button mButton;
    private TextView mText;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_activity);
        mButton = (Button) findViewById(R.id.btn1);
        mText = (TextView) findViewById(R.id.tv1); 
        mText.setText("今天是星期三"); 
        EventBus.getDefault().register(this);
        jumpActivity();
    }

    private void jumpActivity() {

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void Event(MessageEvent messageEvent) {
        mText.setText(messageEvent.getMessage());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
    }

}

事件處理

在這裡,事件的處理執行緒在主執行緒,是因為,我要讓TextView去顯示值。
在 SecondActivity裡去進行事件的傳送。

package com.example.lenovo.tezs;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import org.greenrobot.eventbus.EventBus;

/**
 * Created by ZZG on 2018/1/10.
 */

public class SecondActivity extends AppCompatActivity {
    private Button mButton2;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);
        mButton2=(Button) findViewById(R.id.btn2);
        jumpActivity();
    }

    private void jumpActivity() {
        mButton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new MessageEvent("歡迎大家瀏覽我寫的部落格"));
                finish();
            }
        });
    }
}

很簡單,當點選按鈕的時候,傳送了一個事件。

執行程式。

1.PNG

在FirstActivity中,左邊是一個按鈕,點選之後可以跳轉到SecondActivity,在按鈕的右邊是一個TextView,用來進行結果的驗證。

2.PNG

這是SecondActivity,在頁面的左上角,是一個按鈕,當點選按鈕,就會發送了一個事件,最後這個Activity就會銷燬掉。

3.PNG

此時我們可以看到,FirstActivity裡的文字已經變成了,我們在SecondActivity裡設定的文字。

總結

經過這個簡單的例子,我們發現EventBus使用起來是如此的方便,當我們的程式碼量變得很多的時候,使用EventBus後你的邏輯非常的清晰,並且程式碼之間高度解耦,在進行元件、頁面間通訊的時候,EventBus是一個不錯的選擇。

Android技術討論Q群:947460837



作者:唱著歌的貓
連結:https://www.jianshu.com/p/f9ae5691e1bb
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。