LocalBroadcastManager從使用到源碼分析

前言

自從工作後好長時間都沒寫博客了,一來是實在太忙,二來也沉不下心來看技術文章心態比之前在學校的時候浮躁很多。最近項目裏面用到了LocalBroadcastManager雖然用起來很簡單但是源碼實現起來確實很值得學習的。所以本文先介紹LocalBroadcastManager的使用,然後再進一步分析源碼的實現和相關的設計模式使用。

1.什麼是LocalBroadcastManager

LocalBroadcastManager是本地廣播管理類,本地廣播作用於應用的內部,廣播數據不會泄露,本應用也不會接收到其他應用的廣播,因此安全性較高本地廣播是在應用內部執行,無需跨進程邏輯,與普通廣播相比效率更高使用簡單,無需靜態註冊。LocalBroadcastManager也稱爲局部通知管理器,這種通知的好處是安全性高,效率也高,適合局部通信,可以用來代替Handler更新UI。

2.LocalBroadcastManager使用實例

本地廣播的使用主要分爲兩個步驟:1.發送端發送廣播,2.接收端接受廣播並進行相關處理。
1.發送廣播

Intent broadCastIntent = new Intent();//新建intent
broadCastIntent.setAction(ACTION_LIVE_DATA_UPDATED);//給intent設置相關的action
LocalBroadcastManager.getInstance(context).sendBroadcast(broadCastIntent);//發送廣播

發送廣播分爲三步:新建一個intent給intent加上action然後獲取LocalBroadcastManager的實例進行發送。
2.接收並處理廣播
接受廣播分爲三步,新建BroadcastReceiver接收類,註冊本地廣播,從本地廣播中註銷。

 //新建一個BroadcastReceiver在onReceive中處理接收到廣播後的邏輯
 BroadcastReceiver mLocalBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
            }
 }
//註冊接收廣播,通過intent附加的action來篩選需要監聽的廣播。註冊廣播後每次監聽到廣播變換的時候就可以在BroadcastReceiver 的onReceive方法中進行處理。

 IntentFilter filter = new IntentFilter();
 filter.addAction(ACTION_LIVE_DATA_UPDATED);
 LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mLocalBroadcastReceiver, filter);
//註銷,當程序銷燬的時候一定要註銷廣播,不然會造成內存泄漏
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mLocalBroadcastReceiver);

3.LocalBroadcastManager的實現原理

由本地廣播的使用過程就很容易知道LocalBroadcastManager使用的是觀察者模式,下面從源碼分析LocalBroadcastManager是怎樣實現這種觀察者模式的。要徹底理解LocalBroadcastManager的實現就要了解LocalBroadcastManager中的數據結構。
3.1LocalBroadcastManager中的主要數據結構
1.ReceiverRecord內部類
ReceiverRecord是靜態內部類,ReceiverRecord是對IntentFilter和Broadcast類的一個組合封裝。代碼如下

 private static final class ReceiverRecord {
        final IntentFilter filter;
        final BroadcastReceiver receiver;
        boolean broadcasting;
        boolean dead;

        ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) {
            filter = _filter;
            receiver = _receiver;
        }

        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder(128);
            builder.append("Receiver{");
            builder.append(receiver);
            builder.append(" filter=");
            builder.append(filter);
            if (dead) {
                builder.append(" DEAD");
            }
            builder.append("}");
            return builder.toString();
        }
    }

ReceiverRecord 的結構如圖所示:

在這裏插入圖片描述
2.BroadcastRecord內部類
BroadcastRecord也是一個靜態內部類,主要包含一個intent和一個ReceiverRecord隊列代碼如下:

    private static final class BroadcastRecord {
        final Intent intent;
        final ArrayList<LocalBroadcastManager.ReceiverRecord> receivers;

        BroadcastRecord(Intent _intent, ArrayList<LocalBroadcastManager.ReceiverRecord> _receivers) {
            this.intent = _intent;
            this.receivers = _receivers;
        }
    }
    

3.mReceivers
mReceivers是一個hashMap裏面的結構如下代碼所示:

HashMap<BroadcastReceiver, ArrayList<LocalBroadcastManager.ReceiverRecord>> mReceivers = new HashMap();

mReceivers中的key是BroadcastReceiver,value是元素爲ReceiverRecord的ArrayList。
4.mActions
mActions也是一個hashMap形式的代碼如下:

HashMap<String, ArrayList<LocalBroadcastManager.ReceiverRecord>> mActions = new HashMap();

mActions和mReceivers的不同點在於mActions中的key是String類型的而mReceivers中的key是BroadcastReceiver的。
5.mPendingBroadcasts
mPendingBroadcasts是一個ArrayList形式代碼如下:

ArrayList<LocalBroadcastManager.BroadcastRecord> mPendingBroadcasts = new ArrayList();

分析LoaclBroadcastManager的源碼最重要的是弄懂mReceivers,mActions,mPendingBroadcasts三者的作用和關係。
mReceivers中用於保存用戶註冊的廣播和相關的過濾條件,下面看看註冊廣播的源代碼:

public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        HashMap var3 = this.mReceivers;
        synchronized(this.mReceivers) {
            LocalBroadcastManager.ReceiverRecord entry = new LocalBroadcastManager.ReceiverRecord(filter, receiver);
            ArrayList<LocalBroadcastManager.ReceiverRecord> filters = (ArrayList)this.mReceivers.get(receiver);
            if (filters == null) {
                filters = new ArrayList(1);
                this.mReceivers.put(receiver, filters);
            }

            filters.add(entry);

            for(int i = 0; i < filter.countActions(); ++i) {
                String action = filter.getAction(i);
                ArrayList<LocalBroadcastManager.ReceiverRecord> entries = (ArrayList)this.mActions.get(action);
                if (entries == null) {
                    entries = new ArrayList(1);
                    this.mActions.put(action, entries);
                }

                entries.add(entry);
            }

        }
    }

由上面的代碼可知,每當註冊一個監聽廣播的時候,由BroadcastReceiver和IntentFilter 組成一個新的Entry並且由BroadcastReceiver作爲key到mReceivers中查找保存有ReceiverRecord的ArrayList,如果沒有就新建一個ArrayList,然後把當前產生的Entry放到ArrayList中。
未完待續…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章