LocalBroadcastReceiver 本地广播。
This class is deprecated.
LocalBroadcastManager is an application-wide event bus and embraces layer violations in your app: any component may listen events from any other.
You can replace usage of LocalBroadcastManager with other implementation of observable pattern, depending on your usecase suitable options may be LiveData or reactive streams.
App 进程内的广播机制,利用 观察者模式,Handler 分发机制实现通知,安全性,无法跨进程,其他程序无法将广播发送 App 进程。
BroadcastReceiver 系统广播,跨 App 通知,静态注册 和 动态注册,在代码中使用 registerReceiver() 方法注册,是全局 BroadcastReceiver。
和 静态注册 android:exported 属性为 true 一致,可以被任意外部应用访问,传递 Intent。
权限访问控制(permission参数),
一、LocalBroadcastReceiver 动态注册
public void registerReceiver(@NonNull BroadcastReceiver receiver,
@NonNull IntentFilter filter) {
synchronized (mReceivers) {
LocalBroadcastManager.ReceiverRecord entry = new LocalBroadcastManager.ReceiverRecord(filter, receiver);
ArrayList<LocalBroadcastManager.ReceiverRecord> filters = mReceivers.get(receiver);
if (filters == null) {
filters = new ArrayList<>(1);
mReceivers.put(receiver, filters);
}
filters.add(entry);
//action 对应 广播
for (int i=0; i<filter.countActions(); i++) {
String action = filter.getAction(i);
ArrayList<LocalBroadcastManager.ReceiverRecord> entries = mActions.get(action);
if (entries == null) {
entries = new ArrayList<LocalBroadcastManager.ReceiverRecord>(1);
mActions.put(action, entries);
}
entries.add(entry);
}
}
}
创建一个本地对象 ReceiverRecord,封装 IntentFilter 和 BroadcastReceiver,内部类。
维护 BroadcastReceiver 和 ReceiverRecord List 的 Map。
广播匹配 intentFilter,每一个 Action,可能匹配多个广播,对应一个 ReceiverRecord 列表。
HashMap<String, ArrayList<ReceiverRecord>> mActions 。
二、发送
sendBroadcast(Intent intent) 方法。
根据 Intent 中 Action,在 mActions 中查找 ArrayList<ReceiverRecord>,
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();
遍历列表,如果 ReceiverRecord 中 intentFilter,匹配 action,data, scheme ,匹配成功,设置 broadcasting 标志。
ReceiverRecord receiver = entries.get(i);
if (receiver.broadcasting) {
continue;
}
int match = receiver.filter.match(action, type, scheme, data,
categories, "LocalBroadcastManager");
构建一个 BroadcastRecord 内部类,加入等待 ArrayList<BroadcastRecord> ,发送主线程消息。
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);
}
}
};
主线程,根据消息执行 executePendingBroadcasts() 方法,处理 等待列表,ArrayList<BroadcastRecord>,copy 到 BroadcastRecord[] brs 数组。
for (int i=0; i<brs.length; i++) {
final LocalBroadcastManager.BroadcastRecord br = brs[i];
final int nbr = br.receivers.size();
for (int j=0; j<nbr; j++) {
final LocalBroadcastManager.ReceiverRecord rec = br.receivers.get(j);
if (!rec.dead) {
rec.receiver.onReceive(mAppContext, br.intent);
}
}
}
数组每一项 ReceiverRecord,receiver 的 onReceive() 方法。
任重而道远