簡介
由前面幾篇我們學習了EventBus的使用、特性等等,這篇我們主要講解的是我們如何在EventBus中如何自定義配置相關事項。還有設置事件的優先級案例分析。
進入代碼
事例說明
在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
。
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
在這個情況下纔能有效。
添加自動生成索引時的一些注意事項。