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 完结
  • 动态注册的逻辑在代码中完结

播送的发送和接纳

播送的发送方法有三种

  1. 有序播送
  2. 无序播送
  3. 粘性播送(已抛弃)
  • 发送播送时能够发送有序播送和无序播送
  • 无序传达会优先处理
  • 有序播送会有时刻约束,超时时刻就会 ANR(也便是说只要有序播送才会 ANR,无序播送不会 ANR)
  • 有序播送 ANR 有两种状况,榜首种便是单个播送处理超越了 10 秒(后台 60 秒),另一种是多个播送超越时刻 是 2 * mConstants.TIMEOUT * numReceivers(TIMEOUT 前台默许是 10 秒,后台默许是 60 秒)
  • 静态播送能够拉起进程(但现在体系约束较严格)

最终用一张图作为总结

BroadcastReceiver源码解析(Android12)