-
使用過程
定義事件:
public class MessageEvent { public final String message; public MessageEvent(String message) { this.message = message; } } 複製程式碼
定義事件回撥(方法名沒有限制):
在MainActivity中定義事件回撥
@Subscribe(threadMode = ThreadMode.MAIN) public void process(MessageEvent event) { Toast.makeText(this, event.message, Toast.LENGTH_LONG).show(); } 複製程式碼
EventBus有5種
ThreadMode
:public enum ThreadMode { //在傳送事件的執行緒執行回撥 POSTING, //在主執行緒執行,如果傳送執行緒是主執行緒,則同步執行回撥;如果不是主執行緒,則把回撥放入主執行緒訊息佇列 MAIN, //直接將回撥放入主執行緒訊息佇列 MAIN_ORDERED, //回撥在子執行緒中執行。如果傳送執行緒非子執行緒,則直接同步執行回撥;如果是主執行緒,則EventBus會新建一個子執行緒,並把所有的這種型別的事件放到這個執行緒中執行 BACKGROUND, //子執行緒非同步執行,一般不是主執行緒,也不是事件傳送執行緒 ASYNC } 複製程式碼
註冊和解綁EventBus監聽
如在MainActivity中進行:
@Override protected void onCreate() { super.onCreate(); EventBus.getDefault().register(this); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } 複製程式碼
傳送事件:
EventBus.getDefault().post(new MessageEvent("hello")); 複製程式碼
-
其他情況的處理
-
傳送的事件沒有監聽器
//傳送了字串,但是沒有對應的字串型別的事件回撥 EventBus.getDefault().post("hello"); 複製程式碼
if (!subscriptionFound) { if (logNoSubscriberMessages) { logger.log(Level.FINE, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } } 複製程式碼
如果配置了
EventBusBuilder
的logNoSubscriberMessages
,會列印日誌;如果配置了
sendNoSubscriberEvent
,則會觸發一個NoSubscriberEvent
事件 -
黏性事件
概念:EventBus會為每個事件型別儲存最近一次的事件。當監聽者進行註冊時,會將快取的事件傳送給它。
使用場景:跨生命週期或者非同步呼叫等場景可以使用
舉例:從MAinActivity跳轉到SecondActivity時,傳送一個黏性事件;在SecondActivity註冊EventBus時,會觸發該黏性事件
EventBus.getDefault().postSticky(new MessageEvent("ss")); Intent it = new Intent(MainActivity.this, SecondActivity.class); MainActivity.this.startActivity(it); 複製程式碼
SecondActivity中定義黏性事件的回撥
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true) public void process(MessageEvent e){ Toast.makeText(this, "sticky", Toast.LENGTH_LONG).show(); } 複製程式碼
在onCreate中向EventBus註冊回撥,就會觸發回撥
EventBus.getDefault().register(this); 複製程式碼
原理(黏性事件分發):
public void postSticky(Object event) { synchronized (stickyEvents) { //1 每種黏性事件最近的一個例項會被儲存 stickyEvents.put(event.getClass(), event); } //2 事件也會繼續分發 // Should be posted after it is putted, in case the subscriber wants to remove immediately post(event); } 複製程式碼
註冊時的處理邏輯:
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { ...... //註冊時,如果回撥方法是黏性的,則會將儲存的黏性事件分發出去,觸發該回撥方法 if (subscriberMethod.sticky) { if (eventInheritance) { Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry<Class<?>, Object> entry : entries) { Class<?> candidateEventType = entry.getKey(); if (eventType.isAssignableFrom(candidateEventType)) { Object stickyEvent = entry.getValue(); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } else { Object stickyEvent = stickyEvents.get(eventType); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } 複製程式碼
-
事件有繼承關係
-
定義了一個回撥,事件型別是Object
@Subscribe(threadMode = ThreadMode.MAIN) public void process(Object event) { Toast.makeText(this, event.toString(), Toast.LENGTH_LONG).show(); } 複製程式碼
當傳送任意其他型別的事件時,也會觸發這個回撥,原因在EventBus中有一個
eventInheritance
變數進行控制,預設為true,會響應該事件及其父類的回撥方法private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { Class<?> eventClass = event.getClass(); boolean subscriptionFound = false; if (eventInheritance) { //需要響應該事件的全部事件型別 List<Class<?>> eventTypes = lookupAllEventTypes(eventClass); int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class<?> clazz = eventTypes.get(h); subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); } } else { subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); } if (!subscriptionFound) { if (logNoSubscriberMessages) { logger.log(Level.FINE, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } } } 複製程式碼
lookupAllEventTypes
方法會遍歷所有的事件型別,包括其父類private static List<Class<?>> lookupAllEventTypes(Class<?> eventClass) { synchronized (eventTypesCache) { List<Class<?>> eventTypes = eventTypesCache.get(eventClass); if (eventTypes == null) { eventTypes = new ArrayList<>(); Class<?> clazz = eventClass; while (clazz != null) { eventTypes.add(clazz); addInterfaces(eventTypes, clazz.getInterfaces()); //事件型別的父類,包括Object clazz = clazz.getSuperclass(); } eventTypesCache.put(eventClass, eventTypes); } return eventTypes; } } 複製程式碼
如果不需要響應該事件的父類的回撥,可以將
eventInheritance
置為false@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //不使用預設的EventBus例項 EventBus.builder().eventInheritance(false).installDefaultEventBus(); EventBus.getDefault().register(this); } 複製程式碼
-
定義了一個回撥,事件型別是SubMessageEvent,繼承自MessageEvent
@Subscribe(threadMode = ThreadMode.MAIN) public void process(MessageEvent event) { Toast.makeText(this, "Object", Toast.LENGTH_LONG).show(); } @Subscribe(threadMode = ThreadMode.MAIN) public void processSub(SubMessageEvent event) { Toast.makeText(this, "SubMessageEvent", Toast.LENGTH_LONG).show(); } 複製程式碼
傳送SubMessageEvent事件,如果
eventInheritance
為true,會觸發上述兩個回撥,否則只會觸發SubMessageEvent的回撥傳送MessageEvent事件,只會觸發MessageEvent的回撥
-
-
訂閱者有繼承關係
SecondActivity繼承自MainActivity,觸發MessageEvent事件,則SecondActivity能夠響應事件回撥
//EventBus.findSubscriberMethods()會呼叫findUsingReflection()或findUsingInfo()尋找註冊類上定義的回撥,會遍歷迴圈到父類中使用Subscribe註解的方法 private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) { FindState findState = prepareFindState(); findState.initForSubscriber(subscriberClass); while (findState.clazz != null) { findUsingReflectionInSingleClass(findState); //在父類中尋找監聽器 findState.moveToSuperclass(); } return getMethodsAndRelease(findState); } private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) { FindState findState = prepareFindState(); findState.initForSubscriber(subscriberClass); while (findState.clazz != null) { findState.subscriberInfo = getSubscriberInfo(findState); if (findState.subscriberInfo != null) { SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods(); for (SubscriberMethod subscriberMethod : array) { if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) { findState.subscriberMethods.add(subscriberMethod); } } } else { findUsingReflectionInSingleClass(findState); } //在父類中尋找監聽器 findState.moveToSuperclass(); } return getMethodsAndRelease(findState); } 複製程式碼
-
錯誤事件
EventBus提供了AsyncExecutor和ThrowableFailureEvent來捕獲異常,併傳送異常事件
過程:
- 建立一個AsyncExecutor例項,配置了執行緒池,EventBus例項,及錯誤事件型別
- 執行一個RunnableEx
- 捕獲執行時異常,並用EventBus傳送一個錯誤事件
//AsyncExecutor中的execute方法,引數型別是RunnableEx,需實現run方法,該方法會丟擲異常 public void execute(final RunnableEx runnable) { threadPool.execute(new Runnable() { @Override public void run() { try { runnable.run(); } catch (Exception e) { Object event; try { event = failureEventConstructor.newInstance(e); } catch (Exception e1) { eventBus.getLogger().log(Level.SEVERE, "Original exception:", e); throw new RuntimeException("Could not create failure event", e1); } if (event instanceof HasExecutionScope) { ((HasExecutionScope) event).setExecutionScope(scope); } eventBus.post(event); } } }); } 複製程式碼
配合ErrorDialogManager可以在接收到錯誤事件時,彈一個DialogFragment
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this); //配置錯誤彈窗的標題和內容 ErrorDialogConfig cfg = new ErrorDialogConfig(getResources(),R.string.app_name, R.string.app_name); cfg.setEventBus(EventBus.getDefault()); //建立fragment ErrorDialogManager.factory = new ErrorDialogFragmentFactory.Support(cfg); //將fragment繫結到activity ErrDialogMgr.attachTo(this); findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AsyncExecutor.create().execute(new AsyncExecutor.RunnableEx() { @Override public void run() throws Exception { Object x = null; //丟擲一個空指標異常 x.toString(); } }); } }); } 複製程式碼
點選按鈕會觸發空指標異常,EventBus觸發一個
ThrowableFailureEvent
事件,ErrorDialogManager
中註冊了對應的回撥,響應後會顯示一個dialog注:由於
ErrorDialogManager
的SupportManagerFragment
和HoneycombManagerFragment
在onResume()
時會呼叫EventBus.register()
方法,但是onEventMainThread(ThrowableFailureEvent event)
沒有增加@Subscribe(threadMode = ThreadMode.MAIN)
註解,會拋異常崩潰。 解決:把這幾個類複製出來,並在onEventMainThread
方法上增加註解,能夠彈窗 這個問題已給EventBus提issue-
呼叫了註冊
register()
,但是沒有定義事件處理回撥,即沒有使用@Subscribe
註解會丟擲一個異常
throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation"); 複製程式碼
-
定義了多個同事件的回撥
@Subscribe(threadMode = ThreadMode.MAIN) public void process1(MessageEvent event) { Toast.makeText(this, "process111", Toast.LENGTH_LONG).show(); } @Subscribe(threadMode = ThreadMode.MAIN) public void process2(MessageEvent event) { Toast.makeText(this, "process222", Toast.LENGTH_LONG).show(); } 複製程式碼
如果定義了
MessageEvent
的兩個回撥方法,當觸發MessageEvent
事件時,只有第一個方法會執行。原始碼解釋:
EventBus.findUsingInfo() => FindState.checkAdd() => FindState.checkAddWithMethodSignature() private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) { methodKeyBuilder.setLength(0); methodKeyBuilder.append(method.getName()); methodKeyBuilder.append('>').append(eventType.getName()); String methodKey = methodKeyBuilder.toString(); Class<?> methodClass = method.getDeclaringClass(); Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass); if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) { // Only add if not already found in a sub class return true; } else { // Revert the put, old class is further down the class hierarchy // 如果同一個事件已經定義過回撥,則使用之前的,不會用新方法替換 subscriberClassByMethodKey.put(methodKey, methodClassOld); return false; } } 複製程式碼
-
使用註解
執行時通過反射查詢註解,會有一些效能損失。EventBus提供了註解處理器,在編譯時生成輔助類,提升效能。
使用過程
配置專案的build.gradle:
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
複製程式碼
配置module的build.gradle:
android {
defaultConfig {
javaCompileOptions {
// 註解處理器引數配置
annotationProcessorOptions {
// 配置引數名和值
arguments = [ eventBusIndex :
'com.example.myapplication.EventBusIndex' ]
}
}
}
}
dependencies {
// 配置註解處理器
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}
複製程式碼
make project之後,在build/source/apt/debug/下可以看到生成的輔助類,可以看到方法有Subscribe註解的類都會把類名與定義的回撥方法都儲存在SUBSCRIBER_INDEX中
package com.example.myapplication;
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 EventBusIndex implements SubscriberInfoIndex {
private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;
static {
SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();
putIndex(new SimpleSubscriberInfo(com.example.hero.myapplication.MainActivity.class, true,
new SubscriberMethodInfo[] {
new SubscriberMethodInfo("process1", com.example.hero.myapplication.event.MessageEvent.class,
ThreadMode.MAIN),
}));
}
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;
}
}
}
複製程式碼
新增生成的輔助類,需要在例項化EventBus之前新增
EventBus.builder().addIndex(new EventBusIndex()).installDefaultEventBus();
EventBus.getDefault().register(this);
複製程式碼
註解處理器
註解處理器主要有三個步驟
- 收集訂閱者,遍歷每個Subscribe註解,把類和方法儲存到一個ListMap中
- 過濾訂閱者,類和方法需要滿足一定的條件
- 生成java檔案
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
...
collectSubscribers(annotations, env, messager);
checkForSubscribersToSkip(messager, indexPackage);
createInfoIndexFile(index);
...
return true;
}
複製程式碼
收集訂閱者
private void collectSubscribers(Set<? extends TypeElement> annotations,
RoundEnvironment env, Messager messager) {
for (TypeElement annotation : annotations) {
//遍歷註解,獲取每個加了註解的方法
Set<? extends Element> elements = env.getElementsAnnotatedWith(annotation);
for (Element element : elements) {
if (element instanceof ExecutableElement) {
ExecutableElement method = (ExecutableElement) element;
//方法不是static,必須是public,且只有一個引數
if (checkHasNoErrors(method, messager)) {
//方法所在的類
TypeElement classElement = (TypeElement)
method.getEnclosingElement();
//methodsByClass是一個ListMap
methodsByClass.putElement(classElement, method);
}
} else {
messager.printMessage(Diagnostic.Kind.ERROR, "@Subscribe is only valid
for methods", element);
}
}
}
}
複製程式碼
過濾訂閱者
private void checkForSubscribersToSkip(Messager messager, String myPackage) {
for (TypeElement skipCandidate : methodsByClass.keySet()) {
TypeElement subscriberClass = skipCandidate;
while (subscriberClass != null) {
//類的修飾符是public,則可見
//類的修飾符是private或protected,則不可見
//類的修飾符是預設的,則需要生成的輔助類的包名與註解所在類的包名一樣
if (!isVisible(myPackage, subscriberClass)) {
boolean added = classesToSkip.add(skipCandidate);
if (added) {
String msg;
if (subscriberClass.equals(skipCandidate)) {
msg = "Falling back to reflection because class is not
public";
} else {
msg = "Falling back to reflection because " + skipCandidate +
" has a non-public super class";
}
messager.printMessage(Diagnostic.Kind.NOTE, msg, subscriberClass);
}
break;
}
List<ExecutableElement> methods = methodsByClass.get(subscriberClass);
if (methods != null) {
for (ExecutableElement method : methods) {
String skipReason = null;
VariableElement param = method.getParameters().get(0);
TypeMirror typeMirror = getParamTypeMirror(param, messager);
//引數型別校驗,DeclaredType表示類或者介面,TypeElement表示類或介面
if (!(typeMirror instanceof DeclaredType) ||
!(((DeclaredType) typeMirror).asElement() instanceof
TypeElement)) {
skipReason = "event type cannot be processed";
}
if (skipReason == null) {
TypeElement eventTypeElement = (TypeElement) ((DeclaredType) typeMirror).asElement();
//類的修飾符是public,則可見
//類的修飾符是private或protected,則不可見
//類的修飾符是預設的,則需要生成的輔助類的包名與註解所在類的包名一樣
if (!isVisible(myPackage, eventTypeElement)) {
skipReason = "event type is not public";
}
}
if (skipReason != null) {
boolean added = classesToSkip.add(skipCandidate);
if (added) {
String msg = "Falling back to reflection because " + skipReason;
if (!subscriberClass.equals(skipCandidate)) {
msg += " (found in super class for " + skipCandidate + ")";
}
messager.printMessage(Diagnostic.Kind.NOTE, msg, param);
}
break;
}
}
}
subscriberClass = getSuperclass(subscriberClass);
}
}
}
複製程式碼
生成java類
//index:在build.gradle中配置的註解處理器的引數——生成類的檔名,包含包名
private void createInfoIndexFile(String index) {
BufferedWriter writer = null;
try {
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(index);
int period = index.lastIndexOf('.');
//解析包名和類名
String myPackage = period > 0 ? index.substring(0, period) : null;
String clazz = index.substring(period + 1);
writer = new BufferedWriter(sourceFile.openWriter());
if (myPackage != null) {
writer.write("package " + myPackage + ";\n\n");
}
//寫入各種依賴
writer.write("import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;\n");
writer.write("import org.greenrobot.eventbus.meta.SubscriberMethodInfo;\n");
writer.write("import org.greenrobot.eventbus.meta.SubscriberInfo;\n");
writer.write("import org.greenrobot.eventbus.meta.SubscriberInfoIndex;\n\n");
writer.write("import org.greenrobot.eventbus.ThreadMode;\n\n");
writer.write("import java.util.HashMap;\n");
writer.write("import java.util.Map;\n\n");
writer.write("/** This class is generated by EventBus, do not edit. */\n");
writer.write("public class " + clazz + " implements SubscriberInfoIndex {\n");
//定義靜態常量
writer.write(" private static final Map<Class<?>, SubscriberInfo>
SUBSCRIBER_INDEX;\n\n");
writer.write(" static {\n");
writer.write(" SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>
();\n\n");
//呼叫putIndex方法,把收集的所有類和類中的全部註解方法儲存到SUBSCRIBER_INDEX中
writeIndexLines(writer, myPackage);
writer.write(" }\n\n");
//定義新增回撥資訊的方法
writer.write(" private static void putIndex(SubscriberInfo info) {\n");
writer.write(" SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);\n");
writer.write(" }\n\n");
//實現介面,獲取類的訂閱資訊,包含了所有有註解的方法資訊
writer.write(" @Override\n");
writer.write(" public SubscriberInfo getSubscriberInfo(Class<?>
subscriberClass) {\n");
writer.write(" SubscriberInfo info =
SUBSCRIBER_INDEX.get(subscriberClass);\n");
writer.write(" if (info != null) {\n");
writer.write(" return info;\n");
writer.write(" } else {\n");
writer.write(" return null;\n");
writer.write(" }\n");
writer.write(" }\n");
writer.write("}\n");
} catch (IOException e) {
throw new RuntimeException("Could not write source for " + index, e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
//Silent
}
}
}
}
複製程式碼
EventBus對生成類的處理過程
- 使用生成的輔助類獲取對應類的訂閱資訊
- 將訂閱資訊中的SubscriberMethodInfo轉換為SubscriberMethod
- 將每個方法和事件型別新增到對應的Map中
- 如果沒有註解生成類,則使用反射來獲取這個類中每個註解方法的資訊
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState);
if (findState.subscriberInfo != null) {
SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
for (SubscriberMethod subscriberMethod : array) {
if (findState.checkAdd(subscriberMethod.method,
subscriberMethod.eventType)) {
findState.subscriberMethods.add(subscriberMethod);
}
}
} else {
findUsingReflectionInSingleClass(findState);
}
findState.moveToSuperclass();
}
return getMethodsAndRelease(findState);
}
複製程式碼
獲取類的訂閱者資訊
private SubscriberInfo getSubscriberInfo(FindState findState) {
if (findState.subscriberInfo != null &&
findState.subscriberInfo.getSuperSubscriberInfo() != null) {
SubscriberInfo superclassInfo =
findState.subscriberInfo.getSuperSubscriberInfo();
if (findState.clazz == superclassInfo.getSubscriberClass()) {
return superclassInfo;
}
}
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
//從輔助類中獲取訂閱資訊
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
複製程式碼
簡單的效能對比
在一個類中定義多個回撥,增加Subscribe註解,分別使用反射和編譯時註解,比較register()的耗時:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.builder().addIndex(new EventBusIndex()).installDefaultEventBus();
long start = System.currentTimeMillis();
EventBus.getDefault().register(this);
Log.i("EventBus","register spend="+(System.currentTimeMillis()- start));
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(MessageEvent event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(A event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(B event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(C event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(D event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(E event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(F event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(G event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void process(H event) {
Toast.makeText(this, "process111", Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
複製程式碼
多次執行結果:
- 使用編譯時註解基本只有方法呼叫的耗時,非常少,日誌顯示為0~1ms
- 執行時反射,耗時一般在3~4ms