Android LocalBroadcastManager 的使用总结
轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/53105494
本文出自【趙彥軍的博客】
前言
在Android中,Broadcast是一種廣泛運用的在應用程序之間傳輸信息的機制。我們拿廣播電臺來做個比方。我們平常使用收音機收音是這樣的:許許多多不同的廣播電臺通過特定的頻率來發(fā)送他們的內容,而我們用戶只需要將頻率調成和廣播電臺的一樣就可以收聽他們的內容了。Android中的廣播機制就和這個差不多的道理。
BroadcastReceiver安全問題
BroadcastReceiver設計的初衷是從全局考慮可以方便應用程序和系統(tǒng)、應用程序之間、應用程序內的通信,所以對單個應用程序而言BroadcastReceiver是存在安全性問題的(惡意程序腳本不斷的去發(fā)送你所接收的廣播)。為了解決這個問題LocalBroadcastManager就應運而生了。
LocalBroadcastManager
LocalBroadcastManager是Android Support包提供了一個工具,用于在同一個應用內的不同組件間發(fā)送Broadcast。LocalBroadcastManager也稱為局部通知管理器,這種通知的好處是安全性高,效率也高,適合局部通信,可以用來代替Handler更新UI
- 好處:
1、因廣播數據在本應用范圍內傳播,你不用擔心隱私數據泄露的問題。
2、不用擔心別的應用偽造廣播,造成安全隱患。
3、相比在系統(tǒng)內發(fā)送全局廣播,它更高效。
LocalBroadcastManager用法
LocalBroadcastManager對象的創(chuàng)建
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;
注冊廣播接收器
LocalBroadcastManager.registerReceiver( broadcastReceiver , intentFilter );
發(fā)送廣播
LocalBroadcastManager.sendBroadcast( intent ) ;
取消注冊廣播接收器
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);}}};}從這個部分源碼可以看出兩點:
在獲取LocalBroadcastManager對象實例的時候,這里用了單例模式。并且把外部傳進來的Context 轉化成了ApplicationContext,有效的避免了當前Context的內存泄漏的問題。這一點我們在設計單例模式框架的時候是值得學習的,看源碼可以學習到很多東西。
在LocalBroadcastManager構造函數中創(chuàng)建了一個Handler.可見 LocalBroadcastManager 的本質上是通過Handler機制發(fā)送和接收消息的。
在創(chuàng)建Handler的時候,用了 context.getMainLooper() , 說明這個Handler是在Android 主線程中創(chuàng)建的,廣播接收器的接收消息的時候會在Android 主線程,所以我們決不能在廣播接收器里面做耗時操作,以免阻塞UI。
一個小例子
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);//注冊廣播接收器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();//取消注冊廣播,防止內存泄漏localBroadcastManager.unregisterReceiver( broadcastReceiver );} }運行結果
D/tttt 消息:主線程發(fā)過來的消息: 線程: main D/tttt 消息:子線程發(fā)過來的消息: 線程: main可以看出,廣播接收器的onReceive方法運行在主線程。
注意事項
雖然LocalBroadcastManager也通過BroadcastReceiver來接收消息,但是他們兩個之間還是有很多區(qū)別的。
LocalBroadcastManager注冊廣播只能通過代碼注冊的方式。傳統(tǒng)的廣播可以通過代碼和xml兩種方式注冊。
LocalBroadcastManager注冊廣播后,一定要記得取消監(jiān)聽。這一步可以有效的解決內存泄漏的問題。
LocalBroadcastManager注冊的廣播,您在發(fā)送廣播的時候務必使用LocalBroadcastManager.sendBroadcast(intent); 否則您接收不到廣播。傳統(tǒng)的發(fā)送廣播的方法:context.sendBroadcast( intent );
總結
以上是生活随笔為你收集整理的Android LocalBroadcastManager 的使用总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android EventBus 3.0
- 下一篇: Android local.proper