广播发送流程笔记
ContextImpl
1、sendBroadcast、sendOrderedBroadcast、sendStickyBroadcast
这里主要列举了三种发送的方法:普通广播、有序广播、粘性广播(过时)。
其中有序广播2
是可以传入一个resultReceiver
,可以确保这个receiver
最后一定能收得到广播,这种发送方式是会创建一个InnerReceiver
用来找到我们设置进去的resultReceiver
的
//-----------------普通广播---------------------//
public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
...
try {
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
getUserId());
}
...
}
//-----------------有序广播 1---------------------//
void sendOrderedBroadcast(Intent intent,
String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData,
Bundle initialExtras, Bundle options) {
IIntentReceiver rd = null;
if (resultReceiver != null) {
if (mPackageInfo != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
resultReceiver, getOuterContext(), scheduler,
mMainThread.getInstrumentation(), false);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
}
}
...
try {
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, receiverPermissions, appOp,
options, true, false, getUserId());
}
...
}
//-----------------有序广播 2---------------------//
@Override
public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
String[] receiverPermissions = receiverPermission == null ? null
: new String[] {
receiverPermission};
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
null, true, false, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
//------------------粘性广播(废弃)----------------------//
@Override
@Deprecated
public void sendStickyBroadcast(Intent intent) {
...
try {
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
getUserId());
}
}
AMS
1、sendBroadcastIntent
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
//调用方法broadcastIntentLocked
return broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, callingUid, callingPid, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
2、broadcastIntentLocked(重要)
这个方法主要做了几件事情:
- 1、如果是粘性广播,将它添加到
mStickyBroadcasts
列表中- 2、找出对应的
静态广播接收器
和动态广播接收器