Subscriber Index(訂閱者索引)是一個(gè)可選擇的優(yōu)化技術(shù)核偿,用來加速初始化subscriber注冊。
利用反射來讀取訂閱類中的訂閱方法信息
通過使用EventBus annotation processor(EventBus注解處理器)署穗,訂閱者索引在編譯期間就會被創(chuàng)建庞瘸。雖然沒有規(guī)定必須使用它端衰,但是由于它在Android中最佳性能坎炼,官方推薦使用此方式。
使用索引的先決條件
注意只有用@Subscriber注解的方法才能被編入索引到禁舷,同時(shí)subscriber類和事件類必須是public彪杉。并且,由于Java注解處理本身的技術(shù)限制牵咙,@Subscribe 注解不能使用在匿名類中派近。
當(dāng)EventBus不能使用索引,它將自動恢復(fù)到在運(yùn)行時(shí)通過反射的方式霜大,因此它也能正常工作构哺,只是變得更慢了。
怎么生成索引战坤?
使用注解處理器
如果你不是使用 Android Gradle Plugin version 2.2.0 或更高版本,請以android-apt方式來配置残拐。
啟用索引生成功能途茫,你需要使用annotationProcessor 屬性把EventBus注解處理器添加到你的build。另外溪食,設(shè)置一個(gè)eventBusIndex參數(shù)去指定你想要產(chǎn)生索引類的全路徑類名囊卜。比如說,添加下面的部分到你的Gradle build 腳本。
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [ eventBusIndex : 'com.example.myapp.MyEventBusIndex' ]
}
}
}
}
dependencies {
compile 'org.greenrobot:eventbus:3.0.0'
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}
我自己試過不行栅组,不知道為什么雀瓢?
使用android-apt
打開App的build.gradle,在dependencies中添加最新的EventBus依賴:
compile 'org.greenrobot:eventbus:3.0.0'
在項(xiàng)目gradle的dependencies中引入apt編譯插件:
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
然后在App的build.gradle中應(yīng)用apt插件玉掸,并設(shè)置apt生成的索引的包名和類名:
apply plugin: 'com.neenbedankt.android-apt'
apt {
arguments {
eventBusIndex "com.study.sangerzhong.studyapp.MyEventBusIndex"
}
}
接著在App的dependencies中引入EventBusAnnotationProcessor:
apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
在Rebuild Project操作前刃麸,確保有@Subscribe注解的方法,否則不會生成索引類司浪。 Rebuild Project后泊业,就會發(fā)現(xiàn)在\ProjectName\app\build\generated\source\apt\PakageName\ 下看到通過注解處理器生成的索引類,這樣我們便可以在初始化EventBus時(shí)應(yīng)用我們生成的索引了啊易。
在這里會生成類名為MyEventBusIndex的索引類:
/** 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(MainActivity.class, true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEventA", PayEvent.class, ThreadMode.ASYNC),
}));
putIndex(new SimpleSubscriberInfo(MyIntentService.class, true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEventBB", PayEvent.class),
}));
}
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;
}
}
}
可以看出是使用一個(gè)靜態(tài)HashMap來保存訂閱類的相關(guān)信息吁伺,其中包括了訂閱類的class對象,是否需要檢查父類,以及所有事件響應(yīng)函數(shù)的信息租谈。
怎么把索引類應(yīng)用到Android?
當(dāng)你實(shí)例化EventBus時(shí)篮奄,通過以下方式:
EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();
或者,你想要在整個(gè)app中使用設(shè)置了索引類的EventBus實(shí)例作為默認(rèn)單例割去。
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
// Now the default instance uses the given index. Use it like this:
EventBus eventBus = EventBus.getDefault();
對比通過編譯時(shí)反射方式
在3.0版本中窟却,EventBus提供了一個(gè)EventBusAnnotationProcessor注解處理器來在編譯期通過讀取@Subscribe注解,并解析和處理其中所包含的信息劫拗,然后生成java類來保存訂閱者中所有的事件響應(yīng)函數(shù)间校,這樣就比在運(yùn)行時(shí)使用反射來獲得訂閱者中所有事件響應(yīng)函數(shù)的速度要快。
參考
http://greenrobot.org/eventbus/documentation/subscriber-index/