本篇代码基于原生Android Q
一.广播的基本使用
BroadcastReceiver是Android的四大组件之一,其重要性不言而喻。广播可以用来进程内主线程和子线程进行通信,也可以用于进程间通信。下面是广播的基本使用方法:
//定义广播
BroadcastReceiver receiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this,"这是xiaomiapp2",Toast.LENGTH_LONG).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intentFilter=new IntentFilter("a.b.c");
registerReceiver(receiver,intentFilter); //注册广播
......
Intent intent=new Intent(); //发送广播
intent.setAction("a.b.c");
sendBroadcast(intent);
二.广播的注册过程
广播的注册过程从registerReceiver方法开始,我们知道,Context是个抽象类,子类有ContextImpl和ContextWrapper,ContextWrapper的子类有ContextThemeWrapper,我们的Activity继承于ContextThemeWrapper,而Service和Application则是直接继承于ContextWrapper。
registerReceiver方法Activity里面没有,ContextThemeWrapper里面也没有,ContextWrapper里面有,但是是调用的Context的registerReceiver方法,Context是抽象类,ContextImpl实现了这个方法,最终调用到了registerReceiverInternal方法:
这个方法主要干了两件事:
1.通过LoadedApk获得IIntentReceiver实例
2.通过ActivityManagerService将广播注册到AMS当中
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler(); //获取主线程的handler
}
rd = mPackageInfo.getReceiverDispatcher( //获取IIntentReceiver实例
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try { //注册receiver注册到AMS
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
1.LoadedApk获取IIntentReceiver实例,loadedApk为每个receiver生成一个receiverDispatcher,在receiverDispatcher的构造函数里面初始化IIntentReceiver,然后返回。
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
LoadedApk.ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null; //定义map
if (registered) {
map = mReceivers.get(context);
if (map != null) {
rd = map.get(r);
}
}
if (rd == null) {
//初始化ReceiverDispatcher
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
if (registered) {
if (map == null) {
map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
mReceivers.put(context, map);
}
map.put(r, rd);
}
} else {
rd.validate(context, handler);
}
rd.mForgotten = false;
return rd.getIIntentReceiver(); //返回IIntentReceiver
}
}
//ReceiverDispatcher构造函数
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
if (activityThread == null) {
throw new NullPointerException("Handler must not be null");
}
//初始化IIntentReceiver,显然,是个InnerReceiver对象,关于这个,后面会讲到
mIIntentReceiver = new InnerReceiver(this, !registered);
mReceiver = receiver;
mContext = context;
mActivityThread = activityThread;
mInstrumentation = instrumentation;
mRegistered = registered;
mLocation = new IntentReceiverLeaked(null);
mLocation.fillInStackTrace();
}
2.AMS注册广播,对于传入的IIntentReceiver,都会生成一个ReceiverList实例,每个ReceiverList实例对应多个BroadcastFilter,这里多说一句,同一个receiver可以注册多次,每次不同的filter都可以,这表示该receiver可以接收到的所有过滤器。
//IBinder对应前面传入的IIntentReceiver
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
int flags) {
//......粘性广播的一些处理
synchronized (this) {
if (callerApp != null && (callerApp.thread == null
|| callerApp.thread.asBinder() != caller.asBinder())) { //校验
// Original caller already died
return null;
}
//获取receiverList,首次肯定没有
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
if (rl.app != null) { //校验app的receiver总数,最多1000
final int totalReceiversForApp = rl.app.receivers.size();
if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
throw new IllegalStateException("Too many receivers, total of "
+ totalReceiversForApp + ", registered for pid: "
+ rl.pid + ", callerPackage: " + callerPackage);
}
rl.app.receivers.add(rl); //加入到APP的receiver列表中
} else {
try {
receiver.asBinder().linkToDeath(rl, 0);
} catch (RemoteException e) {
return sticky;
}
rl.linkedToDeath = true;
}
//加入到mRegisteredReceivers中
mRegisteredReceivers.put(receiver.asBinder(), rl);
} else if (rl.uid != callingUid) {
throw new IllegalArgumentException(
"Receiver requested to register for uid " + callingUid
+ " was previously registered for uid " + rl.uid
+ " callerPackage is " + callerPackage);
} else if (rl.pid != callingPid) {
throw new IllegalArgumentException(
"Receiver requested to register for pid " + callingPid
+ " was previously registered for pid " + rl.pid
+ " callerPackage is " + callerPackage);
} else if (rl.userId != userId) {
throw new IllegalArgumentException(
"Receiver requested to register for user " + userId
+ " was previously registered for user " + rl.userId
+ " callerPackage is " + callerPackage);
}
//new一个BroadcastFilter
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
if (rl.containsFilter(filter)) {//校验rl里面是否已有,没