android 中的LocalBroadcastManager

對于LocalBroadcastManager在google官方文檔中也說得很清楚,比較簡短杭煎,也很好看懂恩够,可以去看看。
Helper to register for and send broadcasts of Intents to local objects within your process. This has a number of advantages over sending global broadcasts with sendBroadcast(Intent):

  • You know that the data you are broadcasting won't leave your app, so don't need to worry about leaking private data.
  • It is not possible for other applications to send these broadcasts to your app, so you don't need to worry about having security holes they can exploit.
  • It is more efficient than sending a global broadcast through the system.

大體介紹就是這些羡铲,顧名思義蜂桶,本地廣播(注冊),數(shù)據(jù)安全也切,其他app也不能給你發(fā)廣播(接收)扑媚。也比系統(tǒng)廣播高效。

使用十分簡單:
注冊(接收)

protected void onCreate(Bundle savedInstanceState) { 
// TODO Auto-generated method stub
       super.onCreate(savedInstanceState);
        if(savedInstanceState!=null) { 
            if(mLocalBroadcastManager!=null && mBoradCast!=null) { 
              mLocalBroadcastManager.unregisterReceiver(mBoradCast);
              mLocalBroadcastManager=null; 
              mBoradCast=null;
              }
         }
     
     mLocalBroadcastManager=LocalBroadcastManager.getInstance(this); 
     mBoradCast = new MyBroadCast(); IntentFilter intentFilter = new IntentFilter(); 
     //重點(diǎn)在這里雷恃,本地注冊疆股,本地接收。
     mLocalBroadcastManager.registerReceiver(mBoradCast, intentFilter);
}


@Override 
protected void onDestroy() { 
        super.onDestroy();
        if(mLocalBroadcastManager!=null && mBoradCast!=null) { 
           mLocalBroadcastManager.unregisterReceiver(mBoradCast); 
           mLocalBroadcastManager=null; 
          mBoradCast=null; 
        } 
}

發(fā)送:

LocalBroadcastManager lcm=LocalBroadcastManager.getInstance(mContext); 
lcm.sendBroadcast(new Intent(ACTION_LOCATION));//發(fā)送

以上則是簡單的使用倒槐。那么來說說為何呢:有興趣去看看LocalBroadcastManager旬痹。

注冊這里可以看到,它其實(shí)是一個(gè)單例讨越,針對本應(yīng)用進(jìn)程的唱凯。:

public static LocalBroadcastManager More ...getInstance(Context context) { 
      synchronized (mLock) { 
         if (mInstance == null) {
             mInstance = new LocalBroadcastManager(context.getApplicationContext());//應(yīng)用的上下文
         } 
           return mInstance;
       } 
} 
private More ...LocalBroadcastManager(Context context) { 
           mAppContext = context; 
           //用主線程注冊
           handler mHandler = new Handler(context.getMainLooper()) { 
                @Override public void More ...handleMessage(Message msg) { 
                        switch (msg.what) { 
                              case MSG_EXEC_PENDING_BROADCASTS: 
                                       executePendingBroadcasts(); 
                              break; 
                              default:
                                     super.handleMessage(msg); 
                        } 
                   }
           };
 }```

注冊的代碼:

private final HashMap<BroadcastReceiver, ArrayList<IntentFilter>> mReceivers = new HashMap<BroadcastReceiver, ArrayList<IntentFilter>>();
public void More ...registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
synchronized (mReceivers) {
ReceiverRecord entry = new ReceiverRecord(filter, receiver);
ArrayList<IntentFilter> filters = mReceivers.get(receiver);
if (filters == null) {
filters = new ArrayList<IntentFilter>(1);
//這里很明顯是用的一個(gè)HashMap來裝的我們注冊的receiver和filter mReceivers.put(receiver, filters);
}
filters.add(filter);
for (int i=0; i<filter.countActions(); i++) {
String action = filter.getAction(i);
ArrayList<ReceiverRecord> entries = mActions.get(action);
if (entries == null) {
entries = new ArrayList<ReceiverRecord>(1);
mActions.put(action, entries);
}
entries.add(entry);
}
}
}


取消注冊:

public void More ...unregisterReceiver(BroadcastReceiver receiver) {
synchronized (mReceivers) {
ArrayList<IntentFilter> filters = mReceivers.remove(receiver);
if (filters == null) {
return;8
}
for (int i=0; i<filters.size(); i++) {
IntentFilter filter = filters.get(i);
for (int j=0; j<filter.countActions(); j++) {
String action = filter.getAction(j);
ArrayList<ReceiverRecord> receivers = mActions.get(action);
if (receivers != null) {
for (int k=0; k<receivers.size(); k++) {
if (receivers.get(k).receiver == receiver) {
//從Map里移除
receivers.remove(k);
k--;
}
}
if (receivers.size() <= 0) {
mActions.remove(action);
}
}
}
}
}
}```

發(fā)送廣播,截取一部分:

if (receivers != null) {
  for (int i=0; i<receivers.size(); i++) { 
    receivers.get(i).broadcasting = false;
  }  
mPendingBroadcasts.add(new BroadcastRecord(intent, receivers)); 
  if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) { 
    mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS); 
  }
 return true;
}

private void More ...executePendingBroadcasts() {
    while (true) {
       BroadcastRecord[] brs = null;
       synchronized (mReceivers) {
         final int N = mPendingBroadcasts.size();
           if (N <= 0) {
              return; 
           } 
         brs = new BroadcastRecord[N]; 
         mPendingBroadcasts.toArray(brs); 
         mPendingBroadcasts.clear();
       }
     for (int i=0; i<brs.length; i++) {
        BroadcastRecord br = brs[i]; 
        for (int j=0; j<br.receivers.size(); j++) {
          //重點(diǎn)在這里谎痢,每個(gè)注冊的都調(diào)用了我們注冊的onReceive方法(讓其自行接收處理)磕昼。
          br.receivers.get(j).receiver.onReceive(mAppContext, br.intent);
        }
     } 
    } 
}

這就大致了解了工作原理了。使用起來是很方便的节猿,單例效率也高票从。所以如果不是非本地注冊本地接收的漫雕,還是使用LocalBroadcastManager更好。如果是更新圖庫等峰鄙,需要系統(tǒng)接收的除外浸间。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吟榴,隨后出現(xiàn)的幾起案子魁蒜,更是在濱河造成了極大的恐慌,老刑警劉巖吩翻,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兜看,死亡現(xiàn)場離奇詭異,居然都是意外死亡狭瞎,警方通過查閱死者的電腦和手機(jī)细移,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熊锭,“玉大人弧轧,你說我怎么就攤上這事⊥胍螅” “怎么了精绎?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锌妻。 經(jīng)常有香客問我捺典,道長,這世上最難降的妖魔是什么从祝? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任襟己,我火速辦了婚禮,結(jié)果婚禮上牍陌,老公的妹妹穿的比我還像新娘擎浴。我一直安慰自己,他們只是感情好毒涧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布贮预。 她就那樣靜靜地躺著,像睡著了一般契讲。 火紅的嫁衣襯著肌膚如雪仿吞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天捡偏,我揣著相機(jī)與錄音唤冈,去河邊找鬼。 笑死银伟,一個(gè)胖子當(dāng)著我的面吹牛你虹,可吹牛的內(nèi)容都是我干的绘搞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼傅物,長吁一口氣:“原來是場噩夢啊……” “哼夯辖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起董饰,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤蒿褂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卒暂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啄栓,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年介却,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片块茁。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡齿坷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出数焊,到底是詐尸還是另有隱情永淌,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布佩耳,位于F島的核電站遂蛀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏干厚。R本人自食惡果不足惜李滴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛮瞄。 院中可真熱鬧所坯,春花似錦、人聲如沸挂捅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闲先。三九已至状土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伺糠,已是汗流浹背蒙谓。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留训桶,地道東北人彼乌。 一個(gè)月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓泻肯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親慰照。 傳聞我的和親對象是個(gè)殘疾皇子灶挟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354

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