Android源碼學(xué)習(xí)之EventBus

image.png

官方地址: EventBus

EventBus.getDefault()

public class EventBus {
    static volatile EventBus defaultInstance;

    private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
    private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<>();

    private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
    private final Map<Object, List<Class<?>>> typesBySubscriber;
    private final Map<Class<?>, Object> stickyEvents;

    //1、單例設(shè)計模式返回EventBus對象
    public static EventBus getDefault() {
        EventBus instance = defaultInstance;
        if (instance == null) {
            synchronized (EventBus.class) {
                instance = EventBus.defaultInstance;
                if (instance == null) {
                    //2.調(diào)用EventBus構(gòu)造方法
                    instance = EventBus.defaultInstance = new EventBus();
                }
            }
        }
        return instance;
    }
    
    public EventBus() {
        // 3思犁、調(diào)用有參構(gòu)造方法,傳入一個EventBusBuilder對象
        this(DEFAULT_BUILDER);
    }

    EventBus(EventBusBuilder builder) {
        logger = builder.getLogger();

        //這個集合可以根據(jù)事件類型獲取訂閱者
        //key:事件類型谋减,value:訂閱該事件的訂閱者集合
        subscriptionsByEventType = new HashMap<>();

        //訂閱者所訂閱的事件集合
        //key:訂閱者,value:該訂閱者訂閱的事件集合
        typesBySubscriber = new HashMap<>();

        //粘性事件集合
        //key:事件Class對象扫沼,value:事件對象
        stickyEvents = new ConcurrentHashMap<>();
        //Android主線程處理事件
        mainThreadSupport = builder.getMainThreadSupport();
        mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
        //Background事件發(fā)送者
        backgroundPoster = new BackgroundPoster(this);
        //Async事件發(fā)送者
        asyncPoster = new AsyncPoster(this);
        //訂閱者訂閱事件查找對象
        indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
        subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
                builder.strictMethodVerification, builder.ignoreGeneratedIndex);
        logSubscriberExceptions = builder.logSubscriberExceptions;
        logNoSubscriberMessages = builder.logNoSubscriberMessages;
        sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
        sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
        throwSubscriberException = builder.throwSubscriberException;
        eventInheritance = builder.eventInheritance;
        executorService = builder.executorService;
    }
}

這個方法內(nèi)部首先通過單例模式創(chuàng)建一個EventBus對象出爹,在創(chuàng)建EventBus時最終會調(diào)用它的有參構(gòu)造函數(shù),傳入一個EventBus.Builder對象充甚。在這個有參構(gòu)造函數(shù)內(nèi)部對屬性進行初始化以政,其中有幾個比較重要的屬性:subscriptionsByEventType、typesBySubscriber伴找、stickyEvents和subscriberMethodFinder盈蛮,這幾個屬性的作用已經(jīng)在注釋中給出。

EventBus.getDefault().post(Object event)

public class EventBus {

        private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {
        @Override
        protected PostingThreadState initialValue() {
            return new PostingThreadState();
            }
        };

        public void post(Object event) {
        // 1技矮、獲取當(dāng)前線程的PostingThreadState抖誉,這是一個ThreadLocal對象
        PostingThreadState postingState = currentPostingThreadState.get();
        List<Object> eventQueue = postingState.eventQueue;
        eventQueue.add(event);

        if (!postingState.isPosting) {
            postingState.isMainThread = isMainThread();
            postingState.isPosting = true;
            if (postingState.canceled) {
                throw new EventBusException("Internal error. Abort state was not reset");
            }
            try {
                while (!eventQueue.isEmpty()) {
                    postSingleEvent(eventQueue.remove(0), postingState);
                }
            } finally {
                postingState.isPosting = false;
                postingState.isMainThread = false;
            }
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末殊轴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子袒炉,更是在濱河造成了極大的恐慌旁理,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件我磁,死亡現(xiàn)場離奇詭異孽文,居然都是意外死亡,警方通過查閱死者的電腦和手機夺艰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門芋哭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人郁副,你說我怎么就攤上這事减牺。” “怎么了存谎?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵拔疚,是天一觀的道長。 經(jīng)常有香客問我既荚,道長稚失,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任恰聘,我火速辦了婚禮墩虹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘憨琳。我一直安慰自己,他們只是感情好旬昭,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布篙螟。 她就那樣靜靜地躺著,像睡著了一般问拘。 火紅的嫁衣襯著肌膚如雪遍略。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天骤坐,我揣著相機與錄音绪杏,去河邊找鬼。 笑死纽绍,一個胖子當(dāng)著我的面吹牛蕾久,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拌夏,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼僧著,長吁一口氣:“原來是場噩夢啊……” “哼履因!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起盹愚,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤栅迄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后皆怕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毅舆,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年愈腾,在試婚紗的時候發(fā)現(xiàn)自己被綠了憋活。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡顶滩,死狀恐怖余掖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情礁鲁,我是刑警寧澤盐欺,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站仅醇,受9級特大地震影響冗美,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜析二,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一粉洼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叶摄,春花似錦属韧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至会傲,卻和暖如春锅棕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淌山。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工裸燎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泼疑。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓德绿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子脆炎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容