LocalBroadcastManager
在项目中遇到LocalBroadcastManager,看英文大概知道是“管理本地广播”的,翻了一下api文档,发现他就是用来注册,发送本地广播的,用于应用内通信。
Helper to register for and send broadcasts of Intents to local objects within your process. This is has a number of advantages over sending global broadcasts with sendBroadcast(Intent):
用来注册发送本地应用Intent的广播,通过sendBroadcast发送全局的广播有以下优点:
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.
广播的数据不会留在应用内,不用担心泄露私有的数据。
其他应用程序不能发送这些广播到app内,不用担心一些安全漏洞被他们捕捉到。
通过系统发送一个全局的广播会更加有效率。
注意:LocalBroadcastManager发送的广播不能被应用内跨进程接收
总结一下就是,LocalBroadcastManager是用来发送本地广播的,在应用内进行通信,比较安全,高效。
LocalBroadcastManager
下面我们来看一下LocalBroadcastManager的源码实现:
几个方法
getInstance(),获取LocalBroadcastManager实例
// 单例模式
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);
}
}
};
}
registerReceiver(),注册广播
mReceivers是一个HashMap键是Receivers值是ArrayList filter,首先将
传进来的filter add到Receivers对应的ArrayList ,然后ReceiverRecord add到action对应的 ArrayList ,这样就完成注册
public void 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);
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);
}
}
}
sendBroadcast(Intent intent),发送广播
这里首先取出intent的action,然后拿到之前保存action,RecordReceiver的集合
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();
ArrayList<ReceiverRecord> entries = mActions.get(intent.getAction());
if (entries != null) {
ArrayList<ReceiverRecord> receivers = null;
for (int i=0; i<entries.size(); i++) {
ReceiverRecord receiver = entries.get(i);
// 通过match找对应的filter
if (match >= 0) {
if (receivers == null) {
receivers = new ArrayList<ReceiverRecord>();
}
receivers.add(receiver);
receiver.broadcasting = true;
}
}
通过int match = receiver.filter.match()方法去找对应的filter
int match = receiver.filter.match(action, type, scheme, data,categories, "LocalBroadcastManager");
找到之后,将所有注册该filter的广播接收者放到mPendingBroadcasts集合,然后通过handler发送消息。
mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));
if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {
mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);
}
handler收到消息,执行executePendingBroadcasts()
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_EXEC_PENDING_BROADCASTS:
executePendingBroadcasts();
break;
default:
super.handleMessage(msg);
}
}
接下来就遍历广播接收者,执行onReceive方法,这样就完成了一次广播的发送。
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);
}
}
unregister
了解了怎么注册,那么解除也就是将receiver移除集合的逻辑操作了。
总结
通过查看源码,我们发现LocalBroadcastManager的实现也并不是那么复杂,只有有点耐心,是可以搞清楚里面的实现原理的!