EventBus要點記錄

1秋柄、EventBus方法注冊
先從注冊的對象中找到對應(yīng)的方法
1)先從對外聲明的方法找弛作,如果發(fā)生異常,再找全部方法
找全部方法的時候會設(shè)置變量findState.skipSuperClasses = true; 這樣就不用再次找父類的方法了

try {
    // This is faster than getMethods, especially when subscribers are fat classes 
   like Activities
    methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
    // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
    try {
        methods = findState.clazz.getMethods();

2)方法必須是public修飾的华匾,并且不能是抽象 靜態(tài)的方法(可設(shè)置讓其報出異常)
3)方法必須是Subscribe注解修飾映琳,并且方法的參數(shù)必須是有且只有1個(可設(shè)置讓其報出異常)
4)找完本類后,通持├回去找對應(yīng)的父類的方法萨西,(java和android這樣的父類不包括)
5)負責(zé)查找方法的類是FindState,這個用到了享元模式旭旭,方便對象的復(fù)用谎脯,每次用完會把對象的狀態(tài)置為原值,并放入緩存池中
6)如果是粘性方法持寄,會取出對應(yīng)的粘性事件源梭,發(fā)給注冊的這個方法

private void findUsingReflectionInSingleClass(FindState findState) {
    Method[] methods;
    try {
        // This is faster than getMethods, especially when subscribers are fat classes like Activities
        methods = findState.clazz.getDeclaredMethods();
    } catch (Throwable th) {
        // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
        try {
            methods = findState.clazz.getMethods();
        } catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad...
            String msg = "Could not inspect methods of " + findState.clazz.getName();
            if (ignoreGeneratedIndex) {
                msg += ". Please consider using EventBus annotation processor to avoid reflection.";
            } else {
                msg += ". Please make this class visible to EventBus annotation processor to avoid reflection.";
            }
            throw new EventBusException(msg, error);
        }
        findState.skipSuperClasses = true;
    }
    for (Method method : methods) {
        int modifiers = method.getModifiers();
        if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
            Class<?>[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length == 1) {
                Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                if (subscribeAnnotation != null) {
                    Class<?> eventType = parameterTypes[0];
                    if (findState.checkAdd(method, eventType)) {
                        ThreadMode threadMode = subscribeAnnotation.threadMode();
                        findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                    }
                }
            } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                throw new EventBusException("@Subscribe method " + methodName +
                        "must have exactly 1 parameter but has " + parameterTypes.length);
            }
        } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
            String methodName = method.getDeclaringClass().getName() + "." + method.getName();
            throw new EventBusException(methodName +
                    " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
        }
    }
}

二、發(fā)送事件
發(fā)送消息分為發(fā)送正常事件和發(fā)送粘性事件:
發(fā)送粘性事件和發(fā)送正常事件的區(qū)別在于稍味,把粘性事件放到粘性集合中放一份废麻,然后調(diào)用發(fā)送正常事件的方法

    1、 public void post(Object event)
    2模庐、 public void postSticky(Object event) {
    synchronized (stickyEvents) {
        stickyEvents.put(event.getClass(), event);
    }
    // Should be posted after it is putted, in case the subscriber wants to remove immediately
    post(event);
}

發(fā)送事件分為以下幾步:
1烛愧、把發(fā)送的事件放入待發(fā)送的集合中
2、找到這個事件的所有父類和實現(xiàn)的接口(允許事件繼承關(guān)系的話掂碱,可通過變量設(shè)置)
3怜姿、遍歷第2步中找到的所有事件,根據(jù)事件找到對應(yīng)的方法疼燥,進行執(zhí)行
根據(jù)事件找方法的操作為從map集合中找沧卢,key為這個事件的類型,value為存放了所有監(jiān)聽這個事件的方法的集合
4醉者、方法執(zhí)行中但狭,涉及到在哪個線程執(zhí)行的問題
EvenBus中方法所在的線程分為五種:
1)POSTING 方法執(zhí)行線程和發(fā)事件的線程在同一個線程披诗,這樣可能會引起阻塞,必須等一個方法執(zhí)行完后熟空,才能把事件傳遞個下一個方法
2)MAIN 方法在主線程執(zhí)行藤巢,如果發(fā)送事件的線程也在主線程,也可能會造成阻塞息罗,需要等方法執(zhí)行完后掂咒,才會傳遞給下一個方法
3)MAIN_ORDERED 方法在主線程執(zhí)行,不會對發(fā)送事件造成阻塞迈喉,會把監(jiān)聽該事件的方法放到handler的消息隊列中執(zhí)行
4)BACKGROUND 子線程中執(zhí)行绍刮,如果發(fā)送事件的線程不是主線程,則直接會在這個線程中執(zhí)行挨摸,這種情況同樣可能會引起阻塞孩革,必須等一個方法執(zhí)行完后,才能把事件傳遞個下一個方法
5)ASYNC 子線程中執(zhí)行得运,總是保持和發(fā)送事件的線程不在同一個線程膝蜈,會通過線程池進行執(zhí)行方法

三、取消注冊事件
這一步比較簡單熔掺,eventBus里面有一個map集合饱搏,key為對應(yīng)的注冊的對象類,value為list集合置逻,里面保存著和這對象類有關(guān)的所有event事件類型推沸。
1、根據(jù)這個對象找出所有的事件類型券坞,
2鬓催、然后再根據(jù)事件類型從另一個集合中找出事件類型所對應(yīng)的所有方法
3、遍歷這些方法恨锚,移除掉屬于這個對象類的方法
取消注冊事件就算成功了

在注冊時宇驾,會根據(jù)是否用到了注冊索引類來進行注冊,這個是在編譯階段就把對應(yīng)的方法找到了眠冈,可以提高執(zhí)行效率飞苇,以后再進行分析

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蜗顽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雨让,老刑警劉巖雇盖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異栖忠,居然都是意外死亡崔挖,警方通過查閱死者的電腦和手機贸街,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門赡译,熙熙樓的掌柜王于貴愁眉苦臉地迎上來予弧,“玉大人,你說我怎么就攤上這事钻洒∨Ь椋” “怎么了逸尖?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瘸右。 經(jīng)常有香客問我娇跟,道長,這世上最難降的妖魔是什么太颤? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任苞俘,我火速辦了婚禮,結(jié)果婚禮上龄章,老公的妹妹穿的比我還像新娘吃谣。我一直安慰自己,他們只是感情好做裙,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布岗憋。 她就那樣靜靜地躺著,像睡著了一般菇用。 火紅的嫁衣襯著肌膚如雪澜驮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天惋鸥,我揣著相機與錄音杂穷,去河邊找鬼。 笑死卦绣,一個胖子當(dāng)著我的面吹牛耐量,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滤港,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼廊蜒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了溅漾?” 一聲冷哼從身側(cè)響起山叮,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎添履,沒想到半個月后屁倔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡暮胧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年锐借,在試婚紗的時候發(fā)現(xiàn)自己被綠了问麸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡钞翔,死狀恐怖严卖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情布轿,我是刑警寧澤哮笆,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站驮捍,受9級特大地震影響疟呐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜东且,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一启具、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧珊泳,春花似錦鲁冯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秧了,卻和暖如春跨扮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背验毡。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工衡创, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晶通。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓璃氢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狮辽。 傳聞我的和親對象是個殘疾皇子一也,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353