EventBus的配置&事件的優先順序&使用索引(四)
簡介
由前面幾篇我們學習了EventBus的使用、特性等等,這篇我們主要講解的是我們如何在EventBus中如何自定義配置相關事項。還有設定事件的優先順序案例分析。

EventBus-Android的釋出 - 訂閱
進入程式碼
事例說明
在EventBus的官方文件中也提到了EventBusBuilder類配置EventBus的各個方面事項。例如:以下是如何構建一個在釋出的事件沒有訂閱者的情況下保持靜態的EventBus:
EventBus eventBus = EventBus.builder() .logNoSubscriberMessages(false) .sendNoSubscriberEvent(false) .build();
另一個例子是當訂閱者丟擲異常時失敗:
EventBus eventBus = EventBus.builder().throwSubscriberException(true).build();
配置預設的EventBus例項
使用EventBus.getDefault()是從應用程式中的任何位置獲取共享EventBus例項的簡單方法。EventBusBuilder還允許使用installDefaultEventBus ()方法配置此預設例項 。
例如,可以配置預設的EventBus例項以重新丟擲訂閱者方法中發生的異常。但是,僅限於DEBUG構建,因為這可能會使應用程式在例外情況下崩潰:
EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();
如何使用
優先順序
優先順序priority使用
接下來我們來學習EventBus的優先順序 priority
表示。 priority
來表示優先順序,數值越大,優先順序越高。在同一傳遞執行緒(ThreadMode)中,較高優先順序的訂戶將在優先順序較低的其他訂戶之前接收事件。預設優先順序為0。
- 注:優先順序不會影響具有不同ThreadModes的訂閱者的傳遞順序!
@Subscribe(priority = 1); public void onEvent(MessageEvent event) { //do something }
取消事件傳遞
我們知道事件的優先順序越高接收的資料最快,所以當優先順序不想分發事件給低級別的事件時,可以使用 cancelEventDelivery (Object event)
這裡的引數是訂閱的實體引數。如下程式碼。
- 注:當優先順序更高的想取消事件傳遞時,只有當
threadMode = ThreadMode.POSTING
處於此狀態才能取消事件傳遞有效。其他不行
@Subscribe(priority = 1000,threadMode = ThreadMode.POSTING) public void onEvent(MessageEvent event){ textView.setText(event.message);//設定接收的資料 //取消事件傳遞,則低級別的事件無法接收到資訊,只有在threadMode = ThreadMode.POSTING情況下 EventBus.getDefault().cancelEventDelivery(event) ; }
配置索引
訂戶索引是EventBus 3的新功能。它是一種可選的優化,可加快初始訂戶註冊。可以使用EventBus批註處理器在構建期間建立訂戶索引。雖然不需要使用索引,但建議在Android上獲得最佳效能。
當EventBus無法使用索引時,它將在執行時自動回退到反射。因此它仍然可以工作,只是有點慢。所以新增索引可以讓EventBus的使用效率更高。
如何生成索引
使用 annotationProcessor
如果您沒有使用Android Gradle Plugin 2.2.0或更高版本,請使用android-apt配置。
要啟用索引生成,您需要使用annotationProcessor 屬性將EventBus批註處理器新增到構建中 。還要設定引數 eventBusIndex以指定要生成的索引的完全限定類。例如,將以下部分新增到app builde.radle構建指令碼中:
android { defaultConfig { javaCompileOptions { annotationProcessorOptions { arguments = [ eventBusIndex : 'com.example.myapp.MyEventBusIndex' ] ##這裡要修改為你專案的包名 } } } } dependencies { implementation 'org.greenrobot:eventbus:3.1.1' annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1' }
如果使用Kotlin,是用 kapt
apply plugin: 'kotlin-kapt' // ensure kapt plugin is applied dependencies { implementation 'org.greenrobot:eventbus:3.1.1' kapt 'org.greenrobot:eventbus-annotation-processor:3.1.1' } kapt { arguments { arg('eventBusIndex', 'com.example.myapp.MyEventBusIndex') } }
如果版本級別比較低則使用,(不推薦,應該升級了Gradle)
buildscript { dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } apply plugin: 'com.neenbedankt.android-apt' dependencies { compile 'org.greenrobot:eventbus:3.1.1' apt 'org.greenrobot:eventbus-annotation-processor:3.1.1' } apt { arguments { eventBusIndex "com.example.myapp.MyEventBusIndex" #這裡要修改為你專案的包名 } }
我的Module:app下build.gladle
apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { applicationId "com.eirunye.eventbus" minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" javaCompileOptions { # 新增的索引配置 annotationProcessorOptions { arguments = [ eventBusIndex : 'com.eirunye.eventbus.MyEventBusIndex' ]#這裡要修改為你專案的包名 } } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility = '1.8' targetCompatibility = '1.8' } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' # 新增的索引配置 annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1' implementation 'org.greenrobot:eventbus:3.1.1' }
配置完成後重新Rebuild Project專案,然後我們到 \app\build\generated\source\apt\debug\package\
檢視是否生成所配置的的檔案 MyEventBusIndex
。

MyEventBusIndex.png
package com.eirunye.eventbus; import org.greenrobot.eventbus.meta.SimpleSubscriberInfo; import org.greenrobot.eventbus.meta.SubscriberMethodInfo; import org.greenrobot.eventbus.meta.SubscriberInfo; import org.greenrobot.eventbus.meta.SubscriberInfoIndex; import org.greenrobot.eventbus.ThreadMode; import java.util.HashMap; import java.util.Map; /** This class is generated by EventBus, do not edit. */ public class MyEventBusIndex implements SubscriberInfoIndex { private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX; static { SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>(); putIndex(new SimpleSubscriberInfo(PriorityTestActivity.class, true, new SubscriberMethodInfo[] { new SubscriberMethodInfo("onEvent", com.eirunye.eventbus.bean.MessageEvent.class, ThreadMode.POSTING, 1000, false), new SubscriberMethodInfo("onEventLow", com.eirunye.eventbus.bean.MessageEvent.class, ThreadMode.BACKGROUND, 1, false), })); putIndex(new SimpleSubscriberInfo(MainActivity.class, true, new SubscriberMethodInfo[] { new SubscriberMethodInfo("onMessageEvent", com.eirunye.eventbus.bean.MessageEvent.class), })); putIndex(new SimpleSubscriberInfo(StickyTestActivity.class, true, new SubscriberMethodInfo[] { new SubscriberMethodInfo("onMessageStickyEvent", com.eirunye.eventbus.bean.MessageEvent.class, ThreadMode.MAIN, 0, true), })); } private static void putIndex(SubscriberInfo info) { SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info); } @Override public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) { SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass); if (info != null) { return info; } else { return null; } } }
如何使用索引
我們可以在Application裡面進行初始化。
EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();
如下程式碼:
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus(); } }
如果您想在整個應用中使用預設例項如下
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus(); // Now the default instance uses the given index. Use it like this: EventBus eventBus = EventBus.getDefault();
您可以將相同的原則應用於作為庫的一部分的程式碼(而不是最終的應用程式)。這樣,您可以擁有多個索引類,您可以在EventBus設定期間新增這些索引類如下:
EventBus eventBus = EventBus.builder() .addIndex(new MyEventBusAppIndex()) .addIndex(new MyEventBusLibIndex()).build();
注意:在第一次使用預設EventBus例項之前,這隻能執行一次。對 installDefaultEventBus()
的後續呼叫 將引發異常。這可確保您的應用中的行為一致。所以應該在 Application.class
使用配置,和使用索引。
程式碼混淆
在開發中使用程式碼混淆的時候需要加上。
-keepattributes *Annotation* -keepclassmembers class * { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } # Only required if you use AsyncExecutor -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable); }
總結
EventBus的Configuration配置和索引使用的時候注意 installDefaultEventBus()
只能呼叫一次。否則報錯。
事件的優先順序中設定的值越大優先順序越高,取消事件傳遞,必須是 threadMode = ThreadMode.POSTING
在這個情況下才能有效。
新增自動生成索引時的一些注意事項。
推薦
- 我的部落格
- ofollow,noindex"> Eirunye部落格https://eirunye.github.io