android源码剖析目录
一 概述
BroadcastReceiver 作为 Android 的四大组件之一,也是出场比较频频的,今天咱们就来看看 BroadcastReceiver 是怎么工作的。由于 BroadcastReceiver 分为两个部分,一个是播送发送者,一个是播送承受者,所以本文也会分为两个部分介绍,首要是播送承受者。
二 BroadcastReceiver 简介
首要简单回顾一下 BroadcastReceiver 的两种运用方法,别离是静态注册和动态注册。如下,便是 google 官方供给给咱们的 BroadcastReceiver 运用示例。
静态注册
<receiver android:name=".MyBroadcastReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
</intent-filter>
</receiver>
动态注册
BroadcastReceiver br = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
this.registerReceiver(br, filter);
播送类的界说
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
final PendingResult pendingResult = goAsync();
Task asyncTask = new Task(pendingResult, intent);
asyncTask.execute();
}
private static class Task extends AsyncTask<String, Integer, String> {
private final PendingResult pendingResult;
private final Intent intent;
private Task(PendingResult pendingResult, Intent intent) {
this.pendingResult = pendingResult;
this.intent = intent;
}
@Override
protected String doInBackground(String... strings) {
StringBuilder sb = new StringBuilder();
sb.append("Action: " + intent.getAction() + "\n");
sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
String log = sb.toString();
Log.d(TAG, log);
return log;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// Must call finish() so the BroadcastReceiver can be recycled.
pendingResult.finish();
}
}
}
发送播送
android 供给了三种发送播送的方法
- sendOrderedBroadcast(Intent, String)
- sendBroadcast(Intent)
- LocalBroadcastManager.sendBroadcast
如下,便是其间一种发送播送的代码示例。
Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data","Notice me senpai!");
sendBroadcast(intent);
// 带权限的播送
sendBroadcast(new Intent("com.example.NOTIFY"),
Manifest.permission.SEND_SMS);
// 接纳方需求注册以下权限
<uses-permission android:name="android.permission.SEND_SMS"/>
关于播送的运用,这儿就介绍这么多,不进行扩展了,这些都归于根底内容,咱们接下来看看播送详细的工作原理。
播送由于涉及到发送端和注册端,所以咱们需求从两个端进行剖析,首要咱们剖析注册端。
三 动态注册
播送的注册分为两种,静态注册和动态注册,静态注册是由 PMS 完结的,动态注册则是由咱们运用自己完结的,所以咱们先看动态注册。
动态注册也是从 Context 出发,别离经过以下调用
- ContextWrapper.java -> registerReceiver
- ContextImpl.java -> registerReceiver
- ContextImpl.java -> registerReceiverInternal
3.1 registerReceiver
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
int flags) {
return registerReceiver(receiver, filter, null, null, flags);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext(), 0);
}
3.2 registerReceiverInternal
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
// 榜首部分便是创建了一个 IIntentReceiver 目标
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
// 第二部分便是调用 AMS 的 registerReceiverWithFeature
try {
... // 省掉代码
final Intent intent = ActivityManager.getService().registerReceiverWithFeature(
mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(),
AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId,
flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
// TODO: determine at registration time if caller is
// protecting themselves with signature permission
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
getAttributionSource());
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
这儿分为两个部分
榜首部分 首要是通过 PackageInfo 获取一个 IIntentReceiver,由于播送一般都规划到了跨进程的传递,所以需求将咱们传入的 BroadcastReceiver 封装成一个 IIntentReceiver,用来跨进程传递。
第二部分 然后就和其他的四大组件一样,在 registerReceiverInternal 中调用 AMS 的 registerReceiverWithFeature。到此就通过 Binder 调用到了 AMS 地点的体系进程了。
3.3 IIntentReceiver
在 AMS 中,通过调用 mPackageInfo.getReceiverDispatcher 取得了一个 IIntentReceiver,这个 mPackageInfo 是 LoadedApk。
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);
}
}
// 假如没有复用的,就新建一个 ReceiverDispatcher
if (rd == null) {
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();
}
}
3.4 ReceiverDispatcher 的结构函数
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
if (activityThread == null) {
throw new NullPointerException("Handler must not be null");
}
// 回来的 mIIntentReceiver 其实便是 ReceiverDispatcher 的内部类 InnerReceiver
mIIntentReceiver = new InnerReceiver(this, !registered);
mReceiver = receiver;
mContext = context;
mActivityThread = activityThread;
mInstrumentation = instrumentation;
mRegistered = registered;
mLocation = new IntentReceiverLeaked(null);
mLocation.fillInStackTrace();
}
一切这儿最终拿到的 rd.getIIntentReceiver 其实便是 ReceiverDispatcher 的内部类 InnerReceiver。关于 ReceiverDispatcher 的介绍就先到这儿,更详细的介绍见 [10 ReceiverDispatcher]。
四 LoadedApk
4.1 getReceiverDispatcher
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);
}
}
// 假如调集里没有,就结构一个 ReceiverDispatcher
if (rd == null) {
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
if (registered) {
// 然后再存到 map 调集
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();
}
}
4.2 ReceiverDispatcher
ReceiverDispatcher 是 LoadedApk 中的一个内部类。
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
Log.wtf(TAG, "Null intent received");
rd = null;
} else {
rd = mDispatcher.get();
}
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
+ " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
}
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast to unregistered receiver");
IActivityManager mgr = ActivityManager.getService();
try {
if (extras != null) {
extras.setAllowFds(false);
}
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
ReceiverDispatcher 中有一个 InnerReceiver 的静态内部类,看来它便是完结 IIntentReceiver.Stub 的类,这个便是用来进行跨进程通信的。再来看一看 AMS 中是怎么注册播送的。
五 ActivityManagerService
5.1 registerReceiverWithFeature
public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,
String callerFeatureId, String receiverId, IIntentReceiver receiver,
IntentFilter filter, String permission, int userId, int flags) {
... // 省掉代码
synchronized (this) {
IApplicationThread thread;
if (callerApp != null && ((thread = callerApp.getThread()) == null
|| thread.asBinder() != caller.asBinder())) {
// Original caller already died
return null;
}
// mRegisteredReceivers 是一个 map,首要是从这个 map 中取
// 看看是否有能够复用的 ReceiverList
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
// 假如没有,就用传递进来的 receiver 结构出一个 ReceiverList
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
if (rl.app != null) {
final int totalReceiversForApp = rl.app.mReceivers.numberOfReceivers();
// 这儿会有一个播送数量的判别,超出最大数量就会报错
// MAX_RECEIVERS_ALLOWED_PER_APP 的值是1000
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.mReceivers.addReceiver(rl);
} else {
try {
receiver.asBinder().linkToDeath(rl, 0);
} catch (RemoteException e) {
return sticky;
}
rl.linkedToDeath = true;
}
mRegisteredReceivers.put(receiver.asBinder(), rl);
} else if (rl.uid != callingUid) {
... // 省掉代码
}
// 结构出一个播送过滤器,它是 IntentFilter 的子类。
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, callerFeatureId,
receiverId, permission, callingUid, userId, instantApp, visibleToInstantApps);
if (rl.containsFilter(filter)) {
Slog.w(TAG, "Receiver with filter " + filter
+ " already registered for pid " + rl.pid
+ ", callerPackage is " + callerPackage);
} else {
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
}
mReceiverResolver.addFilter(bf);
}
// 假如有粘性播送,就把它加到粘性播送的行列里
if (allSticky != null) {
ArrayList receivers = new ArrayList();
receivers.add(bf);
final int stickyCount = allSticky.size();
for (int i = 0; i < stickyCount; i++) {
Intent intent = allSticky.get(i);
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
null, null, -1, -1, false, null, null, null, OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1, false, null,
false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}
return sticky;
}
}
到这儿,动态播送的注册流程就算告一段落了,接下来咱们看看静态注册是怎么完结的。
静态注册
静态注册是由体系的 PMS 完结的,体系会在装置 Apk 的时候解析 Apk 的清单文件,然后调用到 PackageParser 的 parseBaseApplication 中。
5.2 parseBaseApplication
[frameworks/base/core/java/android/content/pm/PackageParser.java]
private boolean parseBaseApplication(Package owner, Resources res,
XmlResourceParser parser, int flags, String[] outError)
... // 省掉代码
if (tagName.equals("receiver")) {
Activity a = parseActivity(owner, res, parser, flags, outError, cachedArgs,
true, false);
if (a == null) {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return false;
}
hasReceiverOrder |= (a.order != 0);
owner.receivers.add(a);
}
}
首要是将 receiver 解析成一个 Activity,这儿的 Activity 并不是咱们四大组件之一的 Activity,而是体系中对这四大组件的封装。
然后,将解析处理的 Activity 增加到 owner 的 receivers 调集中。这儿的 owner 是 Package,receivers 是一个泛型是 Activity 的播送承受者调集。
[frameworks/base/core/java/android/content/pm/PackageParser.java]
public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
@UnsupportedAppUsage
public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
@UnsupportedAppUsage
public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
@UnsupportedAppUsage
public final ArrayList<Service> services = new ArrayList<Service>(0);
到这,静态注册就完结了。
六 播送的发送
播送的发送有几种类型,首要咱们从最常用的 sendBroadcast 开端。
6.1 sendBroadcast
播送的发送也是从 Context 开端,经过以下调用
- ContextWrapper.java -> sendBroadcast
- ContextImpl.java -> sendBroadcast
- ActivityManagerService.java -> broadcastIntentWithFeature
6.2 broadcastIntentWithFeature
public final int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, String[] excludedPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
synchronized(this) {
// 首要是校验传入的 intent 是否正确,假如不正确就抛出反常
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLOSP(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, callingFeatureId,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, excludedPermissions, appOp, bOptions, serialized,
sticky, callingPid, callingUid, callingUid, callingPid, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
6.3 broadcastIntentLocked
broadcastIntentLocked 这个函数在 Android 12 中非常长,大约有 800 行,所以这儿我将这个函数分为几个部分来进行解析。
下面,我将 broadcastIntentLocked 分为以下几个部分进行说明
6.3.1 设置播送 flag
intent = new Intent(intent);
final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
// FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS 表明此播送无法运用静态注册的方法接纳
// 这样做是为了避免一些 app 运用静态注册播送的方法拉起自己,完结保活
if (callerInstantApp) {
intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
}
if (userId == UserHandle.USER_ALL && broadcastAllowList != null) {
broadcastAllowList = new int[]{};
}
// 现已停止的运用也不会接纳到播送,避免不断拉起
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
// 假如咱们尚未完结引导,请不要答应发动新进程
if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
// 增加标志,此播送只能动态接纳
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
// 获取userId
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
ALLOW_NON_FULL, "broadcast", callerPackage);
// 保证正在接纳此播送的用户或其 parent 正在运转。假如没有,咱们将越过它。
if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
if ((callingUid != SYSTEM_UID
|| (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
&& !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
// 为关闭播送、晋级步骤设置破例。
return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
}
}
在设置播送 flag 这个阶段,主要给播送增加了如下几个 flag
- FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS -> 此播送是否对 Instant App 可见
- FLAG_EXCLUDE_STOPPED_PACKAGES ->此播送只要活着的运用才干接纳
- FLAG_RECEIVER_REGISTERED_ONLY -> 此播送只能通过动态注册接纳
Instant App 是谷歌供给的一种免装置运用,有兴趣能够自行了解,这儿就不多扩展了。
6.3.2 验证体系权限
final String action = intent.getAction();
BroadcastOptions brOptions = null;
// bOptions 不为空时会检查以下权限,从 AMS 来的 bOptions 都是 null
if (bOptions != null) {
brOptions = new BroadcastOptions(bOptions);
if (brOptions.getTemporaryAppAllowlistDuration() > 0) {
// 检查权限,要求运用有下面三个权限
// CHANGE_DEVICE_IDLE_TEMP_WHITELIST -> 设备的暂时白名单
// START_ACTIVITIES_FROM_BACKGROUND -> 后台发动 Activity
// START_FOREGROUND_SERVICES_FROM_BACKGROUND -> 答应配套运用从后台发动前台服务
if (checkComponentPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED
&& checkComponentPermission(START_ACTIVITIES_FROM_BACKGROUND,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED
&& checkComponentPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(msg);
}
}
if (brOptions.isDontSendToRestrictedApps()
&& !isUidActiveLOSP(callingUid)
&& isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
return ActivityManager.START_CANCELED;
}
if (brOptions.allowsBackgroundActivityStarts()) {
// 检查权限,查运用是否能够后台发动
if (checkComponentPermission(
android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(msg);
} else {
allowBackgroundActivityStarts = true;
backgroundActivityStartsToken = null;
}
}
}
// 验证受维护的播送仅由体系代码发送,并且体系代码仅发送受维护的。
final boolean isProtectedBroadcast;
try {
isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
} catch (RemoteException e) {
return ActivityManager.BROADCAST_SUCCESS;
}
6.3.3 判别体系播送
final boolean isCallerSystem;
// 以下用户发送的都说体系播送
switch (UserHandle.getAppId(callingUid)) {
case ROOT_UID:
case SYSTEM_UID:
case PHONE_UID:
case BLUETOOTH_UID:
case NFC_UID:
case SE_UID:
case NETWORK_STACK_UID:
isCallerSystem = true;
break;
default:
isCallerSystem = (callerApp != null) && callerApp.isPersistent();
break;
}
// 首要进行安全检查:阻挠非体系运用程序发送受维护的播送
if (!isCallerSystem) {
// 假如不是体系播送,就要做以下的判别
if (isProtectedBroadcast) {
throw new SecurityException(msg);
} else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
|| AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
// 兼容性处理
if (callerPackage == null) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " from unknown caller.";
throw new SecurityException(msg);
} else if (intent.getComponent() != null) {
// 它们足以发送到显式组件。。。验证它是否被发送到呼叫运用程序。
if (!intent.getComponent().getPackageName().equals(
callerPackage)) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " to "
+ intent.getComponent().getPackageName() + " from "
+ callerPackage;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
} else {
// Limit broadcast to their own package.
intent.setPackage(callerPackage);
}
}
}
6.3.4 处理播送的 action
取出 action 进行处理,action 是在[6.3.2] 中取得的。
boolean timeoutExempt = false;
if (action != null) {
if (getBackgroundLaunchBroadcasts().contains(action)) {
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
}
switch (action) {
case Intent.ACTION_UID_REMOVED: //uid移除
case Intent.ACTION_PACKAGE_REMOVED: //package移除
case Intent.ACTION_PACKAGE_CHANGED: //package改变
case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:// applications不可用
case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: // applications可用
case Intent.ACTION_PACKAGES_SUSPENDED: // package暂停
case Intent.ACTION_PACKAGES_UNSUSPENDED: // package康复
// 权限判别
if (checkComponentPermission(
android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
callingPid, callingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED) {
// 移除运用是否能够发送播送
throw new SecurityException(msg);
}
... // 省掉代码
if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
final int uid = getUidFromIntent(intent);
if (uid != -1) {
final UidRecord uidRec = mProcessList.getUidRecordLOSP(uid);
if (uidRec != null) {
uidRec.updateHasInternetPermission();
}
}
}
}
这儿涉及到的 action 多达几十种,代码有几百行,这儿就不展开了。
6.3.5 处理粘性播送
关于粘性播送这儿简单说一下,粘性播送是一种持久性的播送,只要不自动移除,就一种存在内存中。谷歌现在现已不引荐运用粘性播送了,发送粘性播送的函数 sendStickyBroadcast 也被标记为 Deprecated。
当然,本着学习的准则,这儿咱们仍是了解一下粘性播送的原理。
// 假如是粘性播送
if (sticky) {
// 首要检查权限
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
callingPid, callingUid)
!= PackageManager.PERMISSION_GRANTED) {
...
throw new SecurityException(msg);
}
if (requiredPermissions != null && requiredPermissions.length > 0) {
return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
}
if (intent.getComponent() != null) {
throw new SecurityException(
"Sticky broadcasts can't target a specific component");
}
// 假如不是针对一切用户的播送,那么久要保证它不与其他用户产生抵触
if (userId != UserHandle.USER_ALL) {
// 从粘性播送中,取出针对一切用户的播送,判别是否存在抵触
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
UserHandle.USER_ALL);
if (stickies != null) {
ArrayList<Intent> list = stickies.get(intent.getAction());
if (list != null) {
int N = list.size();
int i;
for (i=0; i<N; i++) {
if (intent.filterEquals(list.get(i))) {
throw new IllegalArgumentException(
"Sticky broadcast " + intent + " for user "
+ userId + " conflicts with existing global broadcast");
}
}
}
}
}
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
if (stickies == null) {
stickies = new ArrayMap<>();
mStickyBroadcasts.put(userId, stickies);
}
ArrayList<Intent> list = stickies.get(intent.getAction());
if (list == null) {
list = new ArrayList<>();
stickies.put(intent.getAction(), list);
}
final int stickiesCount = list.size();
int i;
for (i = 0; i < stickiesCount; i++) {
// 替换现已存在的 intent
if (intent.filterEquals(list.get(i))) {
list.set(i, new Intent(intent));
break;
}
}
// 将 intent 增加到粘性播送的 list 中
if (i >= stickiesCount) {
list.add(new Intent(intent));
}
}
6.3.6 获取播送承受者
总算到处理播送承受者的地方了。
... // 省掉代码
// 查找静态注册的播送
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
receivers = collectReceiverComponents(
intent, resolvedType, callingUid, users, broadcastAllowList);
}
//找出所以需求接纳此播送的播送承受者
if (intent.getComponent() == null) {
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
for (int i = 0; i < users.length; i++) {
if (mUserController.hasUserRestriction(
UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
continue;
}
List<BroadcastFilter> registeredReceiversForUser =
mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, users[i]);
if (registeredReceivers == null) {
registeredReceivers = registeredReceiversForUser;
} else if (registeredReceiversForUser != null) {
registeredReceivers.addAll(registeredReceiversForUser);
}
}
} else {
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, userId);
}
}
在查找播送承受者的过程中,会先判别发送的播送是否有 FLAG_RECEIVER_REGISTERED_ONLY 标志,此标志表明该播送只能被动态注册者接纳,只要没有该标志的播送,才会去取静态注册的播送。
然后,通过 mReceiverResolver 解析 Intent,获取播送承受者,取得的目标 registeredReceivers 是一个 BroadcastFilter 的调集。
collectReceiverComponents
咱们略微看一下 静态播送的查找逻辑,之前咱们现已说了,静态播送是由 PMS 解析的。
private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
int callingUid, int[] users, int[] broadcastAllowList) {
... // 省掉代码
List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
.queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
}
首要,通过 AppGlobals.getPackageManager 取得 PMS 的 Binder 目标,然后调用 PMS 的 queryIntentReceivers。
queryIntentReceivers
public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
String resolvedType, int flags, int userId) {
return new ParceledListSlice<>(
queryIntentReceiversInternal(intent, resolvedType, flags, userId,
false /*allowDynamicSplits*/));
}
queryIntentReceiversInternal
private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
ComponentName comp = intent.getComponent();
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<>(1);
final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
... // 省掉代码
if (!blockResolution) {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
}
getReceiverInfo
6.3.7 处理并行播送
// 是否用新的Intent 替换旧的 Intent
final boolean replacePending =
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
if (registeredReceivers != null && broadcastAllowList != null) {
// if a uid whitelist was provided, remove anything in the application space that wasn't
// in it.
for (int i = registeredReceivers.size() - 1; i >= 0; i--) {
final int owningAppId = UserHandle.getAppId(registeredReceivers.get(i).owningUid);
if (owningAppId >= Process.FIRST_APPLICATION_UID
&& Arrays.binarySearch(broadcastAllowList, owningAppId) < 0) {
registeredReceivers.remove(i);
}
}
}
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
// 假如咱们没有序列化此播送,请别离发送已注册的接纳器,这样它们就不会等候组件发动。
if (isCallerSystem) {
checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
isProtectedBroadcast, registeredReceivers);
}
// 获取播送承受者的行列
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, excludedPermissions, appOp, brOptions, registeredReceivers,
resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId,
allowBackgroundActivityStarts, backgroundActivityStartsToken,
timeoutExempt);
final boolean replaced = replacePending
&& (queue.replaceParallelBroadcastLocked(r) != null);
// 留意:咱们假定resultTo对于非有序播送为空。
if (!replaced) {
// 将 BroadcastRecord 增加到并行播送
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
6.3.8 兼并播送
// Merge into one list.
int ir = 0;
if (receivers != null) {
// PACKAGE_ADDED的特殊状况:不答应增加的包观看此播送。这避免了他们在装置后当即将其用作后门来运转。
// 也许在未来,咱们希望为运用程序供给一个特殊的装置播送或相似服务,但咱们想故意做出这个决议。
String skipPackages[] = null;
if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
|| Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
|| Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Uri data = intent.getData();
if (data != null) {
String pkgName = data.getSchemeSpecificPart();
if (pkgName != null) {
skipPackages = new String[] { pkgName };
}
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
}
if (skipPackages != null && (skipPackages.length > 0)) {
for (String skipPackage : skipPackages) {
if (skipPackage != null) {
int NT = receivers.size();
for (int it=0; it<NT; it++) {
ResolveInfo curt = (ResolveInfo)receivers.get(it);
if (curt.activityInfo.packageName.equals(skipPackage)) {
receivers.remove(it);
it--;
NT--;
}
}
}
}
}
int NT = receivers != null ? receivers.size() : 0;
int it = 0;
ResolveInfo curt = null;
BroadcastFilter curr = null;
while (it < NT && ir < NR) {
if (curt == null) {
curt = (ResolveInfo)receivers.get(it);
}
if (curr == null) {
curr = registeredReceivers.get(ir);
}
if (curr.getPriority() >= curt.priority) {
// Insert this broadcast record into the final list.
receivers.add(it, curr);
ir++;
curr = null;
it++;
NT++;
} else {
// Skip to the next ResolveInfo in the final list.
it++;
curt = null;
}
}
}
while (ir < NR) {
if (receivers == null) {
receivers = new ArrayList();
}
receivers.add(registeredReceivers.get(ir));
ir++;
}
if (isCallerSystem) {
checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
isProtectedBroadcast, receivers);
}
6.3.9 处理串行播送
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, excludedPermissions, appOp, brOptions,
receivers, resultTo, resultCode, resultData, resultExtras,
ordered, sticky, false, userId, allowBackgroundActivityStarts,
backgroundActivityStartsToken, timeoutExempt);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
final BroadcastRecord oldRecord =
replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
if (oldRecord != null) {
// Replaced, fire the result-to receiver.
if (oldRecord.resultTo != null) {
final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
try {
oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
oldRecord.intent,
Activity.RESULT_CANCELED, null, null,
false, false, oldRecord.userId);
} catch (RemoteException e) {
Slog.w(TAG, "Failure ["
+ queue.mQueueName + "] sending broadcast result of "
+ intent, e);
}
}
} else {
// 处理串行播送
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
} else {
// 没有人对播送感兴趣,但咱们仍然想记录下这件事的产生
if (intent.getComponent() == null && intent.getPackage() == null
&& (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
// This was an implicit broadcast... let's record it for posterity.
addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
}
}
return ActivityManager.BROADCAST_SUCCESS;
6.3.10 小结
以上,便是一切发送播送的过程了,这儿咱们总结一下。
- 动态注册是先于静态注册处理的(也便是动态播送优先级更高)
- 对于部分体系播送,只能够通过动态注册的方法接纳
- 静态注册是能够拉起运用的(现在体系会约束条件)
- 并行播送会先处理,然后再是串行播送(无序先于有序)
接下来咱们再来看看详细的播送处理过程。
七 BroadcastQueue 处理并行播送
接下来,咱们再看看并行播送的处理流程。首要从咱们在 [6.3.7] 中看到的 BroadcastQueue 开端。
7.1 enqueueParallelBroadcastLocked
public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
mParallelBroadcasts.add(r);
enqueueBroadcastHelper(r);
}
mParallelBroadcasts 是 BroadcastQueue 中的一个 ArrayList,保存的是立刻要处理的播送列表。然后咱们再看 [6.3.7] 中,处理并行播送的第二个函数 scheduleBroadcastsLocked。
7.2 scheduleBroadcastsLocked
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
// 发送处理播送的音讯
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
7.3 handleMessage
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
// 处理下一条播送
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
}
八 处理串行播送
然后咱们再看看串行播送的处理流程。首要从咱们在 [6.3.9] 中看到的 BroadcastQueue 开端。
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
8.1 enqueueOrderedBroadcastLocked
public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
mDispatcher.enqueueOrderedBroadcastLocked(r);
enqueueBroadcastHelper(r);
}
在这个函数中,将播送增加进了 mDispatcher 中。,这个 mDispatcher 其实便是 BroadcastDispatcher。
8.2 scheduleBroadcastsLocked
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
// 发送处理播送的音讯 BROADCAST_INTENT_MSG
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
所以不论是串行播送,仍是并行播送,最终都会通过音讯机制,履行到 processNextBroadcast 中。
九 处理播送的逻辑
9.1 processNextBroadcast
private void processNextBroadcast(boolean fromMsg) {
synchronized (mService) {
processNextBroadcastLocked(fromMsg, false);
}
}
9.2 processNextBroadcastLocked
既然处理播送的逻辑都在一个函数里,所以这个函数肯定会别离对串行播送和并行播送做不同的处理。
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
BroadcastRecord r;
mService.updateCpuStats();
if (fromMsg) {
mBroadcastsScheduled = false;
}
// 1. mParallelBroadcasts 是并行播送的调集
// 所以首要处理的并行播送
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
// 2. 调用处理并行播送的函数
deliverToRegisteredReceiverLocked(r,
(BroadcastFilter) target, false, i);
}
//3. 将处理完的并行播送增加到历史记录中
addBroadcastToHistoryLocked(r);
}
// 4. 等候处理的播送,之前在 Service 中也有相似的 mPendingService
// 等进程发动后处理,假如进程以及被杀,就会丢弃此 mPendingService
if (mPendingBroadcast != null) {
boolean isDead;
if (mPendingBroadcast.curApp.getPid() > 0) {
synchronized (mService.mPidsSelfLocked) {
ProcessRecord proc = mService.mPidsSelfLocked.get(
mPendingBroadcast.curApp.getPid());
isDead = proc == null || proc.mErrorState.isCrashing();
}
} else {
final ProcessRecord proc = mService.mProcessList.getProcessNamesLOSP().get(
mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
isDead = proc == null || !proc.isPendingStart();
}
if (!isDead) {
// It's still alive, so keep waiting
return;
} else {
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null;
}
}
boolean looped = false;
// 5. 处理串行播送(有序播送),留意,这儿是一个循环
do {
// 6. 从 mDispatcher 中获取需求处理的串行播送
final long now = SystemClock.uptimeMillis();
r = mDispatcher.getNextBroadcastLocked(now);
// 在循环的开端,会判别播送是否处理完毕
if (r == null) {
// r 为空,表明串行播送处理完毕,直接回来
... // 省掉代码
return;
}
boolean forceReceive = false;
//
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
// 8. 判别播送处理的时刻
// 在处理有序播送时,不只单个播送会超时,多个播送合起来的时刻
// 超越拟定时刻也会超时,触发 ANR
if (mService.mProcessesReady && !r.timeoutExempt && r.dispatchTime > 0) {
if ((numReceivers > 0) &&
(now > r.dispatchTime + (2 * mConstants.TIMEOUT * numReceivers))) {
// 假如播送处理超时,就强制关闭
broadcastTimeoutLocked(false); // forcibly finish this broadcast
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
}
if (r.state != BroadcastRecord.IDLE) {
return;
}
// Is the current broadcast is done for any reason?
if (r.receivers == null || r.nextReceiver >= numReceivers
|| r.resultAbort || forceReceive) {
// Send the final result if requested
if (r.resultTo != null) {
boolean sendResult = true;
// if this was part of a split/deferral complex, update the refcount and only
// send the completion when we clear all of them
if (r.splitToken != 0) {
int newCount = mSplitRefcounts.get(r.splitToken) - 1;
if (newCount == 0) {
// done! clear out this record's bookkeeping and deliver
mSplitRefcounts.delete(r.splitToken);
} else {
// still have some split broadcast records in flight; update refcount
// and hold off on the callback
sendResult = false;
mSplitRefcounts.put(r.splitToken, newCount);
}
}
if (sendResult) {
if (r.callerApp != null) {
mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(
r.callerApp);
}
try {
// 9. 处理串行播送
performReceiveLocked(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false, r.userId);
r.resultTo = null;
} catch (RemoteException e) {
r.resultTo = null;
}
}
}
// 10. 一个播送处理完毕,取消超时音讯
cancelBroadcastTimeoutLocked();
// 11. 把处理过的播送增加到历史中
addBroadcastToHistoryLocked(r);
if (r.intent.getComponent() == null && r.intent.getPackage() == null
&& (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
// This was an implicit broadcast... let's record it for posterity.
mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
}
mDispatcher.retireBroadcastLocked(r);
r = null;
looped = true;
continue;
}
// 检查下一个接纳者是否在延迟策略下,并进行相应处理。 假如当时的播送现已是推迟交付的一部分 追踪的一部分,咱们知道它现在一定是能够按原样交付的,不需求从头延期。
if (!r.deferred) {
final int receiverUid = r.getReceiverUid(r.receivers.get(r.nextReceiver));
if (mDispatcher.isDeferringLocked(receiverUid)) {
// 假如这是播送中仅有的(剩余的)接纳器,"切割 "就没有意义了--只需将其原封不动地推迟,并将其作为当时活动的外发播送退役。当时活动的外发播送。
BroadcastRecord defer;
if (r.nextReceiver + 1 == numReceivers) {
defer = r;
mDispatcher.retireBroadcastLocked(r);
} else {
//
defer = r.splitRecipientsLocked(receiverUid, r.nextReceiver);
// Track completion refcount as well if relevant
if (r.resultTo != null) {
int token = r.splitToken;
if (token == 0) {
// first split of this record; refcount for 'r' and 'deferred'
r.splitToken = defer.splitToken = nextSplitTokenLocked();
mSplitRefcounts.put(r.splitToken, 2);
} else {
// new split from an already-refcounted situation; increment count
final int curCount = mSplitRefcounts.get(token);
mSplitRefcounts.put(token, curCount + 1);
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "New split count for token " + token
+ " is " + (curCount + 1));
}
}
}
}
mDispatcher.addDeferredBroadcast(receiverUid, defer);
r = null;
looped = true;
continue;
}
}
} while (r == null);
// 取得下一个播送接纳者的id
int recIdx = r.nextReceiver++;
// 记录接纳器开端的时刻,必要时呈现 ANR 的话就杀死它。
r.receiverTime = SystemClock.uptimeMillis();
if (recIdx == 0) {
r.dispatchTime = r.receiverTime;
r.dispatchClockTime = System.currentTimeMillis();
}
if (! mPendingBroadcastTimeoutMessage) {
// 设置超时时刻,当时时刻 + TIMEOUT(10秒)
long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
setBroadcastTimeoutLocked(timeoutTime);
}
final BroadcastOptions brOptions = r.options;
final Object nextReceiver = r.receivers.get(recIdx);
if (nextReceiver instanceof BroadcastFilter) {
// 假如下一个是动态注册的播送接纳者
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
if (r.receiver == null || !r.ordered) {
// 假如接纳者现已处理完,就持续处理下一个
r.state = BroadcastRecord.IDLE;
scheduleBroadcastsLocked();
} else {
if (filter.receiverList != null) {
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
}
}
return;
}
// 困难状况:需求实例化接纳器,可能是 发动它的运用进程来承载它。
// 权限判别
ResolveInfo info =
(ResolveInfo)nextReceiver;
ComponentName component = new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
... // 省掉代码,很多权限判别
// Broadcast is being executed, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.curComponent.getPackageName(), false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ r.curComponent.getPackageName() + ": " + e);
}
// 假如播送地点的进程正在运转,就会在这儿处理并回来
if (app != null && app.getThread() != null && !app.isKilled()) {
try {
app.addPackage(info.activityInfo.packageName,
info.activityInfo.applicationInfo.longVersionCode, mService.mProcessStats);
maybeAddAllowBackgroundActivityStartsToken(app, r);
processCurBroadcastLocked(r, app);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when sending broadcast to "
+ r.curComponent, e);
} catch (RuntimeException e) {
Slog.wtf(TAG, "Failed sending broadcast to "
+ r.curComponent + " with " + r.intent, e);
// If some unexpected exception happened, just skip
// this broadcast. At this point we are not in the call
// from a client, so throwing an exception out from here
// will crash the entire system instead of just whoever
// sent the broadcast.
logBroadcastReceiverDiscardLocked(r);
finishReceiverLocked(r, r.resultCode, r.resultData,
r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
// We need to reset the state if we failed to start the receiver.
r.state = BroadcastRecord.IDLE;
return;
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
// 没有回来,说明进程没有运转,先发动进程
r.curApp = mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
new HostingRecord("broadcast", r.curComponent), isActivityCapable
? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY,
(r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false);
if (r.curApp == null) {
// 这个接纳者的进程发动失利,所以处理下一个播送
Slog.w(TAG, "Unable to launch app "
+ info.activityInfo.applicationInfo.packageName + "/"
+ receiverUid + " for broadcast "
+ r.intent + ": process is bad");
logBroadcastReceiverDiscardLocked(r);
finishReceiverLocked(r, r.resultCode, r.resultData,
r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
r.state = BroadcastRecord.IDLE;
return;
}
maybeAddAllowBackgroundActivityStartsToken(r.curApp, r);
mPendingBroadcast = r;
mPendingBroadcastRecvIndex = recIdx;
}
9.3 deliverToRegisteredReceiverLocked
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
... // 省掉代码,很多的权限判别
try {
if (filter.receiverList.app != null && filter.receiverList.app.isInFullBackup()) {
// 假如 app 处于备份状况,就越过有序播送
if (ordered) {
skipReceiverLocked(r);
}
} else {
r.receiverTime = SystemClock.uptimeMillis();
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
maybeScheduleTempAllowlistLocked(filter.owningUid, r, r.options);
// 调用处理播送的逻辑
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
// parallel broadcasts are fire-and-forget, not bookended by a call to
// finishReceiverLocked(), so we manage their activity-start token here
if (filter.receiverList.app != null
&& r.allowBackgroundActivityStarts && !r.ordered) {
postActivityStartTokenRemoval(filter.receiverList.app, r);
}
}
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}
} catch (RemoteException e) {
Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
// Clean up ProcessRecord state related to this broadcast attempt
if (filter.receiverList.app != null) {
filter.receiverList.app.removeAllowBackgroundActivityStartsToken(r);
if (ordered) {
filter.receiverList.app.mReceivers.removeCurReceiver(r);
// Something wrong, its oom adj could be downgraded, but not in a hurry.
mService.enqueueOomAdjTargetLocked(r.curApp);
}
}
// And BroadcastRecord state related to ordered delivery, if appropriate
if (ordered) {
r.receiver = null;
r.curFilter = null;
filter.receiverList.curBroadcast = null;
}
}
}
9.4 performReceiveLocked
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
final IApplicationThread thread = app.getThread();
if (thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
try {
thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser,
app.mState.getReportedProcState());
} catch (RemoteException ex) {
// Failed to call into the process. It's either dying or wedged. Kill it gently.
synchronized (mService) {
Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+ " (pid " + app.getPid() + "). Crashing it.");
app.scheduleCrashLocked("can't deliver broadcast");
}
throw ex;
}
} else {
// Application has died. Receiver doesn't exist.
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
接下来经过一下调用逻辑,就又到了咱们熟悉的 ReceiverDispatcher 了。
- ActivityThread -> scheduleRegisteredReceiver
- IIntentReceiver -> performReceive
10 ReceiverDispatcher
在 ReceiverDispatcher 中,有一个 InnerReceiver,它是 IIntentReceiver.Stub 的子类,所以一开端的跨进程调用,会调用到 InnerReceiver 的 performReceive。
10.1 InnerReceiver.performReceive
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
// 界说一个 rd 目标
final LoadedApk.ReceiverDispatcher rd;
... // 省掉代码
if (rd != null) {
// 调用 rd 的 performReceive
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
... // 省掉代码
IActivityManager mgr = ActivityManager.getService();
try {
if (extras != null) {
extras.setAllowFds(false);
}
// 调用完结播送
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
10.2 ReceiverDispatcher.performReceive
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
// Args 也是 ReceiverDispatcher 的内部类
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
... // 省掉代码
// 调用 Args 的 run
if (intent == null || !mActivityThread.post(args.getRunnable())) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManager.getService();
// 调用 Args 的 sendFinished
args.sendFinished(mgr);
}
}
}
}
10.3 Args 的 run 函数
final class Args extends BroadcastReceiver.PendingResult {
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
final IActivityManager mgr = ActivityManager.getService();
final Intent intent = mCurIntent;
mCurIntent = null;
mDispatched = true;
mRunCalled = true;
... // 反常处理
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
mContext.getAttributionSource());
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
// 调用播送接纳者的 onReceive
receiver.onReceive(mContext, intent);
} catch (Exception e) {
... // 省掉代码
}
10.4 sendFinished
public void sendFinished(IActivityManager am) {
synchronized (this) {
if (mFinished) {
throw new IllegalStateException("Broadcast already finished");
}
mFinished = true;
try {
if (mResultExtras != null) {
mResultExtras.setAllowFds(false);
}
if (mOrderedHint) {
// 调用 AMS 的 finishReceiver
am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
mAbortBroadcast, mFlags);
} else {
// This broadcast was sent to a component; it is not ordered,
// but we still need to tell the activity manager we are done.
am.finishReceiver(mToken, 0, null, null, false, mFlags);
}
} catch (RemoteException ex) {
}
}
}
十一 ActivityManagerService
11.1 finishReceiver
public void finishReceiver(IBinder who, int resultCode, String resultData,
Bundle resultExtras, boolean resultAbort, int flags) {
// Refuse possible leaked file descriptors
if (resultExtras != null && resultExtras.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
}
final long origId = Binder.clearCallingIdentity();
try {
boolean doNext = false;
BroadcastRecord r;
BroadcastQueue queue;
synchronized(this) {
if (isOnFgOffloadQueue(flags)) {
queue = mFgOffloadBroadcastQueue;
} else if (isOnBgOffloadQueue(flags)) {
queue = mBgOffloadBroadcastQueue;
} else {
queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
? mFgBroadcastQueue : mBgBroadcastQueue;
}
r = queue.getMatchingOrderedReceiver(who);
if (r != null) {
doNext = r.queue.finishReceiverLocked(r, resultCode,
resultData, resultExtras, resultAbort, true);
}
if (doNext) {
// 调用 BroadcastQueue 的 processNextBroadcastLocked,分发下一个有序播送
r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
}
trimApplicationsLocked(false, OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
十二 总结
到此,播送的发送和承受就都整理完毕了,最终再来做一个简单的整理。
播送的注册
- 播送的注册分为两种,静态注册和动态注册。
- 静态注册的逻辑由 PMS 完结
- 动态注册的逻辑在代码中完结
播送的发送和接纳
播送的发送方法有三种
- 有序播送
- 无序播送
- 粘性播送(已抛弃)
- 发送播送时能够发送有序播送和无序播送
- 无序传达会优先处理
- 有序播送会有时刻约束,超时时刻就会 ANR(也便是说只要有序播送才会 ANR,无序播送不会 ANR)
- 有序播送 ANR 有两种状况,榜首种便是单个播送处理超越了 10 秒(后台 60 秒),另一种是多个播送超越时刻 是 2 * mConstants.TIMEOUT * numReceivers(TIMEOUT 前台默许是 10 秒,后台默许是 60 秒)
- 静态播送能够拉起进程(但现在体系约束较严格)
最终用一张图作为总结