赞
踩
LocalBroadcastManager是Android Support包提供了一个工具,是用来在同一个应用内的不同组件间发送Broadcast的。
使用LocalBroadcastManager有如下好处:
1. 发送的广播只会在自己App内传播,不会泄露给其他App,确保隐私数据不会泄露
2. 其他App也无法向你的App发送该广播,不用担心其他App会来搞破坏比系统全局广播更加高效
先通过
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
获取实例,然后通过函数 registerReceiver来注册监听器
lbm.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Handle the received local broadcast
}
}, new IntentFilter(LOCAL_ACTION));
通过 sendBroadcast 函数来发送广播
lbm.sendBroadcast(new Intent(LOCAL_ACTION));
以下我们简单来做个Demo,实际体会一下。例子很简单,一个布局文件加一个主Activity。
布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/sendLocal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送本地广播" />
</RelativeLayout>
主Activity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private final String ACTION = "org.bridge.localreceiver.LOCAL_BROADCAST";
private LocalBroadcastManager manager;
private LocalReceiver localReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = LocalBroadcastManager.getInstance(this);
//新建intentFilter
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION);
localReceiver = new LocalReceiver();
manager.registerReceiver(localReceiver, filter);
findViewById(R.id.sendLocal).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sendLocal:
Intent intent = new Intent(ACTION);
manager.sendBroadcast(intent);
// manager.sendBroadcastSync();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
manager.unregisterReceiver(localReceiver);
}
}
点击发送按钮,我们的应用成功收到了广播,接下来我们分析一下,本地广播是如何实现只在当前应用内发送和接受的。
以下是LocalBroadcastManager的源代码,整个类代码量不多,还是较为简单的。
public final class LocalBroadcastManager {
//静态内部类,ReceiverRecord 封装了BroadcastReceiver和IntentFilter
private static class ReceiverRecord {
final IntentFilter filter;
final BroadcastReceiver receiver;
boolean broadcasting;
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);
builder.append("}");
return builder.toString();
}
}
//静态内部类BroadcastRecord ,封装了Intent 和对应的ReceiverRecord
private static class BroadcastRecord {
final Intent intent;
final ArrayList<ReceiverRecord> receivers;
BroadcastRecord(Intent _intent, ArrayList<ReceiverRecord> _receivers) {
intent = _intent;
receivers = _receivers;
}
}
private static final String TAG = "LocalBroadcastManager";
private static final boolean DEBUG = false;
private final Context mAppContext;
//BroadReceiver和对应IntentFilter映射
private final HashMap<BroadcastReceiver, ArrayList<IntentFilter>> mReceivers
= new HashMap<BroadcastReceiver, ArrayList<IntentFilter>>();
private final HashMap<String, ArrayList<ReceiverRecord>> mActions
= new HashMap<String, ArrayList<ReceiverRecord>>();
private final ArrayList<BroadcastRecord> mPendingBroadcasts
= new ArrayList<BroadcastRecord>();
static final int MSG_EXEC_PENDING_BROADCASTS = 1;
private final Handler mHandler;
private static final Object mLock = new Object();
private static LocalBroadcastManager mInstance;
//单例模式获取实例
public static LocalBroadcastManager getInstance(Context context) {
synchronized (mLock) {
if (mInstance == null) {
mInstance = new LocalBroadcastManager(context.getApplicationContext());
}
return mInstance;
}
}
//私有构造方法,构造了一个Handler
private LocalBroadcastManager(Context context) {
mAppContext = context;
mHandler = new Handler(context.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_EXEC_PENDING_BROADCASTS:
executePendingBroadcasts();
break;
default:
super.handleMessage(msg);
}
}
};
}
//注册广播
public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
synchronized (mReceivers) {
ReceiverRecord entry = new ReceiverRecord(filter, receiver);
//从映射表取得receiver对应的IntentFilter
ArrayList<IntentFilter> filters = mReceivers.get(receiver);
//如果没有找到,就添加这个映射
if (filters == null) {
filters = new ArrayList<IntentFilter>(1);
mReceivers.put(receiver, filters);
}
filters.add(filter);
//遍历filter,保存action到mActions中
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 unregisterReceiver(BroadcastReceiver receiver) {
synchronized (mReceivers) {
ArrayList<IntentFilter> filters = mReceivers.remove(receiver);
if (filters == null) {
return;
}
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) {
receivers.remove(k);
k--;
}
}
if (receivers.size() <= 0) {
mActions.remove(action);
}
}
}
}
}
}
//发送广播
public boolean sendBroadcast(Intent intent) {
synchronized (mReceivers) {
final String action = intent.getAction();
final String type = intent.resolveTypeIfNeeded(
mAppContext.getContentResolver());
final Uri data = intent.getData();
final String scheme = intent.getScheme();
final Set<String> categories = intent.getCategories();
final boolean debug = DEBUG ||
((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
if (debug) Log.v(
TAG, "Resolving type " + type + " scheme " + scheme
+ " of intent " + intent);
ArrayList<ReceiverRecord> entries = mActions.get(intent.getAction());
if (entries != null) {
if (debug) Log.v(TAG, "Action list: " + entries);
ArrayList<ReceiverRecord> receivers = null;
for (int i=0; i<entries.size(); i++) {
ReceiverRecord receiver = entries.get(i);
if (debug) Log.v(TAG, "Matching against filter " + receiver.filter);
if (receiver.broadcasting) {
if (debug) {
Log.v(TAG, " Filter's target already added");
}
continue;
}
int match = receiver.filter.match(action, type, scheme, data,
categories, "LocalBroadcastManager");
if (match >= 0) {
if (debug) Log.v(TAG, " Filter matched! match=0x" +
Integer.toHexString(match));
if (receivers == null) {
receivers = new ArrayList<ReceiverRecord>();
}
receivers.add(receiver);
receiver.broadcasting = true;
} else {
if (debug) {
String reason;
switch (match) {
case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
default: reason = "unknown reason"; break;
}
Log.v(TAG, " Filter did not match: " + reason);
}
}
}
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;
}
}
}
return false;
}
//发送同步广播
public void sendBroadcastSync(Intent intent) {
if (sendBroadcast(intent)) {
executePendingBroadcasts();
}
}
private void 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++) {
br.receivers.get(j).receiver.onReceive(mAppContext, br.intent);
}
}
}
}
}
mReceivers存储广播和过滤器信息,以BroadcastReceiver作为key,IntentFilter链表作为value.mReceivers是接收器和IntentFilter的对应表,主要作用是方便在unregisterReceiver()取消注册,同时作为对象锁限制注册接收器,发送广播,取消接收器注册等几个过程的并发访问。
mActions 以Action为key,注册这个Action的BroadCastReceiver链表为value.mActions的主要作用是方便在广播发送后快速得到可以接受它的BroadCastReceiver.
先根据Action从mActions 中取出ReceiverRecord列表,循环每个ReceiverRecord 判断filter和intent 中action,type,scheme,data,categoried 是否match,是的话则保存到receivers列表中,发送what为 MSG_EXEC_PENDING_BROADCASTS的消息,通过Handler处理。
mPendingBroadcasts转换为数组BroadcastRecord,循环每个receiver,调用其onReceive函数,这样便完成了广播的核心逻辑。
从mReceivers及mActions中移除相应元素。
LocalBroadcastManager 的核心实现实际上还是Handler,只是利用到了IntentFilter的match功能,至于BroadcastReceiver换成其他接口也无所谓,顺便利用了现成的类和概念而已。
因为采用了Handler实现了应用内通信,自然安全性更好,效率更高。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。