Android LocalBroadcastManager 的使用总结
轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/zhaoyanjun6/article/details/53105494
本文出自【趙彥軍的博客】
前言
在Android中,Broadcast是一種廣泛運(yùn)用的在應(yīng)用程序之間傳輸信息的機(jī)制。我們拿廣播電臺(tái)來做個(gè)比方。我們平常使用收音機(jī)收音是這樣的:許許多多不同的廣播電臺(tái)通過特定的頻率來發(fā)送他們的內(nèi)容,而我們用戶只需要將頻率調(diào)成和廣播電臺(tái)的一樣就可以收聽他們的內(nèi)容了。Android中的廣播機(jī)制就和這個(gè)差不多的道理。
BroadcastReceiver安全問題
BroadcastReceiver設(shè)計(jì)的初衷是從全局考慮可以方便應(yīng)用程序和系統(tǒng)、應(yīng)用程序之間、應(yīng)用程序內(nèi)的通信,所以對(duì)單個(gè)應(yīng)用程序而言BroadcastReceiver是存在安全性問題的(惡意程序腳本不斷的去發(fā)送你所接收的廣播)。為了解決這個(gè)問題LocalBroadcastManager就應(yīng)運(yùn)而生了。
LocalBroadcastManager
LocalBroadcastManager是Android Support包提供了一個(gè)工具,用于在同一個(gè)應(yīng)用內(nèi)的不同組件間發(fā)送Broadcast。LocalBroadcastManager也稱為局部通知管理器,這種通知的好處是安全性高,效率也高,適合局部通信,可以用來代替Handler更新UI
- 好處:
1、因廣播數(shù)據(jù)在本應(yīng)用范圍內(nèi)傳播,你不用擔(dān)心隱私數(shù)據(jù)泄露的問題。
2、不用擔(dān)心別的應(yīng)用偽造廣播,造成安全隱患。
3、相比在系統(tǒng)內(nèi)發(fā)送全局廣播,它更高效。
LocalBroadcastManager用法
LocalBroadcastManager對(duì)象的創(chuàng)建
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;
注冊(cè)廣播接收器
LocalBroadcastManager.registerReceiver( broadcastReceiver , intentFilter );
發(fā)送廣播
LocalBroadcastManager.sendBroadcast( intent ) ;
取消注冊(cè)廣播接收器
LocalBroadcastManager.unregisterReceiver( broadcastReceiver );
LocalBroadcastManager部分源碼解析
private static LocalBroadcastManager mInstance;public static LocalBroadcastManager getInstance(Context context) {synchronized (mLock) {if (mInstance == null) {mInstance = new LocalBroadcastManager(context.getApplicationContext());}return mInstance;}}private LocalBroadcastManager(Context context) {mAppContext = context;mHandler = new Handler(context.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_EXEC_PENDING_BROADCASTS:executePendingBroadcasts();break;default:super.handleMessage(msg);}}};}從這個(gè)部分源碼可以看出兩點(diǎn):
在獲取LocalBroadcastManager對(duì)象實(shí)例的時(shí)候,這里用了單例模式。并且把外部傳進(jìn)來的Context 轉(zhuǎn)化成了ApplicationContext,有效的避免了當(dāng)前Context的內(nèi)存泄漏的問題。這一點(diǎn)我們?cè)谠O(shè)計(jì)單例模式框架的時(shí)候是值得學(xué)習(xí)的,看源碼可以學(xué)習(xí)到很多東西。
在LocalBroadcastManager構(gòu)造函數(shù)中創(chuàng)建了一個(gè)Handler.可見 LocalBroadcastManager 的本質(zhì)上是通過Handler機(jī)制發(fā)送和接收消息的。
在創(chuàng)建Handler的時(shí)候,用了 context.getMainLooper() , 說明這個(gè)Handler是在Android 主線程中創(chuàng)建的,廣播接收器的接收消息的時(shí)候會(huì)在Android 主線程,所以我們決不能在廣播接收器里面做耗時(shí)操作,以免阻塞UI。
一個(gè)小例子
package com.app;import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AppCompatActivity; import android.util.Log;public class MainActivity extends AppCompatActivity {private LocalBroadcastManager localBroadcastManager ;private MyBroadcastReceiver broadcastReceiver ;private IntentFilter intentFilter ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//注冊(cè)廣播接收器localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;broadcastReceiver = new MyBroadcastReceiver() ;intentFilter = new IntentFilter( "myaction") ;localBroadcastManager.registerReceiver( broadcastReceiver , intentFilter );//在主線程發(fā)送廣播Intent intent = new Intent( "myaction" ) ;intent.putExtra( "data" , "主線程發(fā)過來的消息" ) ;localBroadcastManager.sendBroadcast( intent ) ;new Thread(new Runnable() {@Overridepublic void run() {//在子線程發(fā)送廣播Intent intent = new Intent( "myaction" ) ;intent.putExtra( "data" , "子線程發(fā)過來的消息" ) ;localBroadcastManager.sendBroadcast( intent ) ;}}).start(); ;}private class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction() ;if ( "myaction".equals( action )){Log.d( "tttt 消息:" + intent.getStringExtra( "data" ) , "線程: " + Thread.currentThread().getName() ) ;}}}@Overrideprotected void onDestroy() {super.onDestroy();//取消注冊(cè)廣播,防止內(nèi)存泄漏localBroadcastManager.unregisterReceiver( broadcastReceiver );} }運(yùn)行結(jié)果
D/tttt 消息:主線程發(fā)過來的消息: 線程: main D/tttt 消息:子線程發(fā)過來的消息: 線程: main可以看出,廣播接收器的onReceive方法運(yùn)行在主線程。
注意事項(xiàng)
雖然LocalBroadcastManager也通過BroadcastReceiver來接收消息,但是他們兩個(gè)之間還是有很多區(qū)別的。
LocalBroadcastManager注冊(cè)廣播只能通過代碼注冊(cè)的方式。傳統(tǒng)的廣播可以通過代碼和xml兩種方式注冊(cè)。
LocalBroadcastManager注冊(cè)廣播后,一定要記得取消監(jiān)聽。這一步可以有效的解決內(nèi)存泄漏的問題。
LocalBroadcastManager注冊(cè)的廣播,您在發(fā)送廣播的時(shí)候務(wù)必使用LocalBroadcastManager.sendBroadcast(intent); 否則您接收不到廣播。傳統(tǒng)的發(fā)送廣播的方法:context.sendBroadcast( intent );
總結(jié)
以上是生活随笔為你收集整理的Android LocalBroadcastManager 的使用总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android EventBus 3.0
- 下一篇: Java 反射 使用总结