簡潔的 EventBus 實現:Android xBus

jopen 9年前發布 | 18K 次閱讀 Android開發 移動開發 Android xBus

xBus 是基于發布訂閱(Pub/Sub)模式的一個事件消息庫,使用通用的register(target),unregister(target),post(event)消息通信接口,能有效的減少甚至消除Android應用中異步任務邏輯和界面更新之間的耦合,實現模塊化,提高開發效率。

使用指南

Gradle 集成

    compile 'com.mcxiaoke.xbus:bus:1.0.+'

接收事件

public class SimpleActivity extends Activity {
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 注冊
        Bus.getDefault().register(this);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 取消注冊
        Bus.getDefault().unregister(this);
    }
    @BusReceiver
    public void onStringEvent(String event) {
        // handle your event
        // 這里處理事件
    }
    @BusReceiver
    public void onSomeEvent(SomeEventClass event) {
        // SomeEventClass表示任意的自定義類
        // handle your event
        // 這里處理事件
    }
    @BusReceiver
    public void onObjectEvent(Object event) {
        // 不建議使用Object,會收到所有類型的事件
        // handle your event
        // 這里處理事件
    }
}

發送事件

然后在需要的地方調用post(event)發送事件通知,如Service或某個線程里,可以在任何地方發送事件:

// 比如在IntentService里
public class SimpleService extends IntentService {
    public SimpleService() {
        super("SimpleService");
    }
    @Override
    protected void onHandleIntent(final Intent intent) {
       // 這里是舉例,可以在任何地方發送事件
        Bus.getDefault().post("String Event");
        Bus.getDefault().post(new SomeEventClass());
        Bus.getDefault().post(new Object());
    }
}

高級用法

任何地方注冊

你還可以選擇在onStart()里注冊,在onStop()里取消注冊。你完全可以在任何地方注冊和取消注冊,沒有任何限制。但是建議你在生命周期事件方法里注冊和取消注冊,如Activity/Fragment/Service的onCreate/onDestroy方法里,register()和unregister()建議配對使用,避免內存泄露。

 @Override
    protected void onStart() {
        super.onStart();
        // you can also register here
        Bus.getDefault().register(this);
    }
    @Override
    protected void onStop() {
        super.onStop();
        // you can also unregister here
        Bus.getDefault().unregister(this);
    }

自定義Bus

你也可以不使用默認的Bus.getDefault(),改用自己創建的Bus對象:

public class MainApp extends Application {
    private Bus mBus = new Bus();
    @Override
    public void onCreate() {
        super.onCreate();
    }
    public Bus getBus() {
        return mBus;
    }
}

Debug

默認不輸出任何LOG信息,可以這樣啟用調試模式:

public Bus setDebug(final boolean debug)

MethodFinder

默認使用注解(@BusReceiver)識別事件接收器方法,可以這樣修改 :

public Bus setMethodFinder(final MethodFinder finder)

默認使用的是 AnnotationMethodFinder,只有使用了 @BusReceiver 的方法才可以接受事件。

可選使用NamedMethodFinder,NamedMethodFinder使用方法名識別,默認方法名是onEvent,你可以指定其它的方法名。

使用NamedMethodFinder會比使用AnnotationMethodFinder效率高一點,因為它忽略注解,直接使用方法名字符串匹配。一般使用,兩者差別不大。

你還可以實現MethodFinder接口,自定義其它的事件接收器方法匹配模式:

interface MethodFinder {

    Set<MethodInfo> find(final Bus bus, final Class<?> targetClass);
}

StrictMode

寬泛匹配模式

默認情況下,Bus使用寬泛的事件類型匹配模式,事件參數會匹配它的父類和接口,如果你調用post(String),那么這幾個方法都會收到舉例:

// 如果你調用這個方法,發送一個StringBuilder類型的事件
Bus.getDefault().post(new StringBuilder("Event"));
// 這幾個方法會收到事件
public void onEvent1(StringBuilder event) // 匹配,類型相符
public void onEvent2(Object event) // 匹配,StringBuilder是Object的子類
public void onEvent3(CharSequence event) // 匹配,StringBuilder是CharSequence的實現類
public void onEvent4(Serializable event) // 匹配,StringBuilder實現了Serializable接口
// 這幾個方法不會收到事件
public void onEvent5(Exception event) 不匹配,Exception與String完全無關
public void onEvent6(String event) // 不匹配,StringBuilder不能轉換成String類型

對于post(event)和onEvent(EventType),匹配規則是:如果  event.getClass() 可以強制轉換成EventType,那么匹配成功,能收到事件。

嚴格匹配模式

可以使用下面的方法更改默認行為,使用嚴格的事件類型匹配模式:

public Bus setStrictMode(final boolean strictMode)

啟用嚴格匹配模式后,發送和接受方法的參數類型必須嚴格匹配才能收到事件,舉例:

// setStrictMode(true) 啟用嚴格模式后:
Bus.getDefault().post(new StringBuilder("Event"));
// 只有 onEvent1 能收到事件
public void onEvent1(StringBuilder event)
public void onEvent2(Object event)public void onEvent3(CharSequence event) 
public void onEvent4(Serializable event)
public void onEvent5(Exception event)
public void onEvent6(String event)

對于post(event)和onEvent(EventType),嚴格模式的匹配規則是當且僅當event.getClass().equals(EventType)時才能收到事件。

說明:啟用嚴格模式效率會稍微高一點,因為不會遞歸查找event的父類和實現的接口,但是由于Bus內部使用了緩存,對于同一個事件類型,并不會重復查找,所以實際使用幾乎沒有差別。

StickyEvent

可以使用下面的方法發送Sticky事件,這種事件會保留在內存中,當下一個注冊者注冊時,會立即收到上一次發送的該類型事件,每種類型的事件只會保留一個,Sticky事件使用嚴格匹配模式。

public <E> void postSticky(E event)

一般不需要使用Sticky事件,但在某些場景下可以用到,比如一個網絡狀態監聽服務,會不斷的發送網絡狀態信息,接受者一旦注冊就可以立即收到一個事件,可以知道當前的網絡狀態。

@BusEvent

還有一個注解@BusEvent可用于標注某個類是事件類,這個像@Override注解一樣,純標注用,沒有其它用途,沒有運行時消耗。

實現教程

項目主頁:http://www.baiduhome.net/lib/view/home/1440248130395

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!