您的位置:首页 > 移动开发 > Android开发

《Android中级工程师》BroadcastReceive工作流程

2017-11-27 17:11 351 查看

前言

关于BroadcastReceive的使用已经了解了很多,但是使用都是应用层的,我们需要了解frameworks层是如何实现的,才能更深层次理解它的工作原理。

关于广播的种类,我们知道大体有三类:

普通广播:通过Context.sendBroadcast()发送,可并行处理

有序广播:通过Context.sendOrderedBroadcast()发送,串行处理

Sticky广播:通过Context.sendStickyBroadcast()发送

这三种广播类型虽然具有不同的特性,但是它们的工作过程都是类似的,所以我们只分析普通广播即可。

关于广播的注册方式,我们知道有两种:

静态注册:通过在AndroidManifest.xml文件声明来注册,类似于Activity和Service

动态注册:通过代码registerReceiver()来注册,这种方式需要在合适的时机进行解注册unregisterReceiver()

这两种方式都能够完成注册广播的功能,其中静态广播的注册是在应用安装时由系统自动通过PackageManagerService(PMS)来完成。所以这里我们为了更好分析它的工程,采用动态注册的方式来研究。

一、时序图



二、 注册过程追踪

1. ContextWrapper.registerReceiver()

public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}


很熟悉,和Service很相似,参考《Android中级工程师》Service启动流程

2. ContextImpl.registerReceiver()

public Intent registerReceiver(//省略参数) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext());
}


3. ContextImpl.registerReceiverInternal()

private Intent registerReceiverInternal(//省略参数) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
//获取主线程
scheduler = mMainThread.getHandler();
}
//获取IIntentReceiver对象
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
//省略部分代码
}
}
try {
//跨进程调用AMS的registerReceiver()
final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}


这里我们看到了一个熟悉的方法,通过getReceiverDispatcher()获取IIntentReceiver对象,具体实现是LoadedApk.ReceiverDispatcher.InnerReceiver,这是一个Binder接口,为了跨进程时进行传输。ReceiverDispatcher内部以键值对的形式保存了BroadcastReceiver和InnerReceiver,所以当接收到广播时,可以很方便的调用BroadcastReceiver的onReceiver()方法。然后注册广播的任务就跨进程的交给了AMS去完成。

4. ActivityManagerService.registerReceiver()

public Intent registerReceiver(//省略参数) {
enforceNotIsolatedCaller("registerReceiver");
ArrayList<Intent> stickyIntents = null;
ProcessRecord callerApp = null;
int callingUid;
int callingPid;
//查询调用者的进程信息
synchronized(this) {
if (caller != null) {
callerApp = getRecordForAppLocked(caller);
//省略部分代码
}
callingUid = callerApp.info.uid;
callingPid = callerApp.pid;
} else {
callerPackage = null;
callingUid = Binder.getCallingUid();
callingPid = Binder.getCallingPid();
}

userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
//获取IntentFilter中的actions,需要监听的广播action
Iterator<String> actions = filter.actionsIterator();
if (actions == null) {
ArrayList<String> noAction = new ArrayList<String>(1);
noAction.add(null);
actions = noAction.iterator();
}

//收集调用者的sticky Intent,保存在列表当中
int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
while (actions.hasNext()) {
String action = actions.next();
for (int id : userIds) {
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
if (stickies != null) {
ArrayList<Intent> intents = stickies.get(action);
if (intents != null) {
if (stickyIntents == null) {
stickyIntents = new ArrayList<Intent>();
}
stickyIntents.addAll(intents);
4000

}
}
}
}
}
//查询匹配的sticky广播,查询成功的添加到allSticky列表中
ArrayList<Intent> allSticky = null;
if (stickyIntents != null) {
final ContentResolver resolver = mContext.getContentResolver();
for (int i = 0, N = stickyIntents.size(); i < N; i++) {
Intent intent = stickyIntents.get(i);
if (filter.match(resolver, intent, true, TAG) >= 0) {
if (allSticky == null) {
allSticky = new ArrayList<Intent>();
}
allSticky.add(intent);
}
}
}

//当IIntentReceiver为空,则直接返回第一个sticky Intent,
Intent sticky = allSticky != null ? allSticky.get(0) : null;
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
if (receiver == null) {
return sticky;
}

synchronized (this) {
if (callerApp != null && (callerApp.thread == null
|| callerApp.thread.asBinder() != caller.asBinder())) {
// 调用者已经被杀死了
return null;
}
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
//对于没有注册的广播,则创建接收者队列
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
if (rl.app != null) {
rl.app.receivers.add(rl);
} else {
try {
//注册死亡通知
receiver.asBinder().linkToDeath(rl, 0);
} catch (RemoteException e) {
return sticky;
}
rl.linkedToDeath = true;
}
//新创建的接收者队列,添加到已注册广播队列
mRegisteredReceivers.put(receiver.asBinder(), rl);
//创建广播过滤者,并添加到接收者队列
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId);
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
}
mReceiverResolver.addFilter(bf);

//所有匹配该filter的sticky广播执行入队操作
//如果没有使用sendStickyBroadcast,则allSticky=null。
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);
//根据intent返回前台或后台广播队列
BroadcastQueue queue = broadcastQueueForIntent(intent);
//创建BroadcastRecord
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1);
//该广播加入到并行广播队列
queue.enqueueParallelBroadcastLocked(r);
//调度广播,发送BROADCAST_INTENT_MSG消息,触发处理下一个广播。
queue.scheduleBroadcastsLocked();
}
}

return sticky;
}
}


mRegisteredReceivers是HashMap结构的,它以receiver IBinder为key, ReceiverList为value为HashMap来记录着所有已注册的广播,这样整个广播的注册过程就完成了。

在BroadcastQueue中有两个广播队列mParallelBroadcasts,mOrderedBroadcasts,数据类型都为ArrayList:

mParallelBroadcasts:并行广播队列,可以立刻执行,而无需等待另一个广播运行完成,该队列只允许动态已注册的广播,从而避免发生同时拉起大量进程来执行广播,前台的和后台的广播分别位于独立的队列。

mOrderedBroadcasts:有序广播队列,同一时间只允许执行一个广播,该队列顶部的广播便是活动广播,其他广播必须等待该广播结束才能运行,也是独立区别前台的和后台的广播。

三、广播注册总结

注册过程:

获取IIntentReceiver对象,其实现类为LoadedApk.ReceiverDispatcher.InnerReceiver,并且将BroadcastReceiver和InnerReceiver保存到ReceiverDispatcher中;

通过ActivityManagerService将获得的InnerReceiver和调用者进程ApplicationThread,以跨进程的方式注册到SystemServer中;

在ActivityManagerService注册时,为当前InnerReceiver创建接受者队列ReceiverList,并且将ReceiverList添加到已注册广播列表mRegisteredReceivers中;

根据当前的filter创建广播过滤者BroadcastFilter,并添加到接受者队列ReceiverList中。

当注册的是Sticky广播时,还会创建BroadcastRecord,并添加到BroadcastQueue的mParallelBroadcasts(并行广播队列),注册后调用AMS来尽快处理该广播。

四、发送广播追踪

1. ContextWrapper.sendBroadcast()

public void sendBroadcast(Intent intent, String receiverPermission) {
mBase.sendBroadcast(intent, receiverPermission);
}


2. ContextImpl.sendBroadcast()

public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}


3. ActivityManagerService.broadcastIntent()

public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
//检查Intent
intent = verifyBroadcastLocked(intent);

final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}


这里需要注意的是这个方法的参数有两个boolean类型的,它们共同作用来决定发送的是什么广播:

类型serializedsticky
sendBroadcastfalsefalse
sendOrderedBroadcasttruefalse
sendStickyBroadcastfalsetrue

4. ActivityManagerService.broadcastIntentLocked()

private final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {

//step1: 设置flag
//step2: 广播权限验证
//step3: 处理系统相关广播
//step4: 增加sticky广播
//step5: 查询receivers和registeredReceivers
//step6: 处理并行广播
//step7: 合并registeredReceivers到receivers
//step8: 处理串行广播

return ActivityManager.BROADCAST_SUCCESS;
}


这里就直接引用gityuan的分布研究了,当然由于版本的原因,有些不一样了。

4.1 设置广播flag

//此flag将导致已停止的应用无法收到此广播
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 = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
ALLOW_NON_FULL, "broadcast", callerPackage);
//确保接收此广播的用户处于运行状态,否则除非是系统升级广播或者关机广播,否则直接返回
if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
if ((callingUid != Process.SYSTEM_UID
|| (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
&& !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
return ActivityManager.BROADCAST_F
11ee1
AILED_USER_STOPPED;
}
}


这里需要注意的是,从Android3.1开始,默认情况下广播不会发送给已经停止的应用,主要是因为系统为Intent添加了两个标记位:

FLAG_EXCLUDE_STOPPED_PACKAGES:广播不会发送给已经停止的应用

FLAG_INCLUDE_STOPPED_PACKAGES:广播会发送给已经停止的应用

BroadcastReceiver的Flags还包括:

FLAG_RECEIVER_REGISTERED_ONLY //只允许已注册receiver接收广播

FLAG_RECEIVER_REPLACE_PENDING //新广播会替代相同广播

FLAG_RECEIVER_FOREGROUND //只允许前台receiver接收广播

FLAG_RECEIVER_NO_ABORT //对于有序广播,先接收到的receiver无权抛弃广播

FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT //Boot完成之前,只允许已注册receiver接收广播

FLAG_RECEIVER_BOOT_UPGRADE //升级模式下,允许系统准备就绪前可以发送广播

4.2 广播权限验证

// 是否是受保护的广播
final String action = intent.getAction();
final boolean isProtectedBroadcast;
try {
isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception", e);
return ActivityManager.BROADCAST_SUCCESS;
}
//是否由系统调用
final boolean isCallerSystem;
switch (UserHandle.getAppId(callingUid)) {
case Process.ROOT_UID:
case Process.SYSTEM_UID:
case Process.PHONE_UID:
case Process.BLUETOOTH_UID:
case Process.NFC_UID:
isCallerSystem = true;
break;
default:
isCallerSystem = (callerApp != null) && callerApp.persistent;
break;
}

// 受保护的广播只能由系统调用,非系统调用的话停止调用者发送该广播
if (!isCallerSystem) {
if (isProtectedBroadcast) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " from pid="
+ callingPid + ", uid=" + callingUid;
Slog.w(TAG, msg);
throw new SecurityException(msg);

} else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
|| AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
//省略部分代码
}
}


4.3 处理系统相关广播

if (action != null) {
switch (action) {
case Intent.ACTION_UID_REMOVED: //uid移除
case Intent.ACTION_PACKAGE_REMOVED: //package移除
case Intent.ACTION_PACKAGE_ADDED: //增加package
case Intent.ACTION_PACKAGE_CHANGED: //package改变
case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: //外部设备不可用
case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: //外部设备可用
case Intent.ACTION_TIMEZONE_CHANGED: //时区改变,通知所有运行中的进程
case Intent.ACTION_TIME_CHANGED: //时间改变,通知所有运行中的进程
case Intent.ACTION_CLEAR_DNS_CACHE: //DNS缓存清空
case Proxy.PROXY_CHANGE_ACTION: //网络代理改变
}
}


4.4 增加Sticky广播

if (sticky) {
//sticky广播必须有BROADCAST_STICKY权限
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
callingPid, callingUid)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
+ callingPid + ", uid=" + callingUid
+ " requires " + android.Manifest.permission.BROADCAST_STICKY;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
//省略部分代码
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++) {
if (intent.filterEquals(list.get(i))) {
//此sticky已存在,则替换掉
list.set(i, new Intent(intent));
break;
}
}
if (i >= stickiesCount) {
//添加新的intent到list中
list.add(new Intent(intent));
}
}


4.5 查询reseivers和registeredReceivers

//查询谁会接收这个广播
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;
//当允许静态接收者处理该广播,则通过PKMS根据Intent查询相应的静态receivers
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if (intent.getComponent() == null) {
if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
//省略部分代码
} else {
//根据Intent查询动态注册的广播
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false, userId);
}
}


其中receivers:记录着匹配当前intent的所有静态注册广播接收者;

registeredReceivers:记录着匹配当前的所有动态注册的广播接收者。

4.6 处理并行广播

final boolean replacePending =
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
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对象
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
resultExtras, ordered, sticky, false, userId);
final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
if (!replaced) {
//将广播加入到并行队列
queue.enqueueParallelBroadcastLocked(r);
//处理广播
queue.scheduleBroadcastsLocked();
}
//动态注册的广播接收者处理完成,则会置空该变量
registeredReceivers = null;
NR = 0;
}


4.7 合并registeredReceivers到receivers

int ir = 0;
if (receivers != null) {
//防止应用监听该广播,在安装时直接运行,属于特殊情况
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);
}
//将skipPackages相关的广播接收者从receivers列表中移除
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--;
}
}
}
}
}
//处理动态广播,处理完后再执行将动态注册的registeredReceivers合并到receivers
int NT = receivers != null ? receivers.size() : 0;
int it = 0;
ResolveInfo curt = null;
BroadcastFilter curr = null;
while (it < NT && ir < NR) {
//省略部分代码
}
}
//完成合并
while (ir < NR) {
if (receivers == null) {
receivers = new ArrayList();
}
receivers.add(registeredReceivers.get(ir));
ir++;
}


4.8 处理串行广播

//存在广播接收者
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
//创建广播队列
BroadcastQueue queue = broadcastQueueForIntent(intent);
//创建BroadcastRecord对象
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
if (!replaced) {
//将广播加入到串行队列中
queue.enqueueOrderedBroadcastLocked(r);
//处理广播
queue.scheduleBroadcastsLocked();
}
} else {
if (intent.getComponent() == null && intent.getPackage() == null
&& (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
}
}


五、发送广播总结

发送过程:

设置flags,默认情况下不会发送给已经停止的应用;

检查广播的权限,受保护的广播只能由系统调用;

处理系统广播;

处理sticky广播,存放在mStickyBroadcasts中;

分别调用scheduleBroadcastsLocked()方法来处理并行广播和串行广播。

处理发送方式:

sticky广播:

创建BroadcastRecord对象;

添加到mParallelBroadcasts队列;

执行queue.scheduleBroadcastsLocked。

并行广播:

只有动态注册的广播才会并行处理,由registeredReceivers来记录

创建BroadcastRecord对象;

将广播加入到mParallelBroadcasts队列;

执行queue.scheduleBroadcastsLocked;

串行广播:

将registeredReceivers中保存的动态注册的广播合并到receivers中。即动态静态一起处理;

创建BroadcastRecord对象;

将广播加入到mOrderedBroadcasts队列;

执行queue.scheduleBroadcastsLocked;

六、接收广播追踪

1. BroadcastQueue.scheduleBroadcastsLocked()

public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}


这里并没有做实际处理,而是发送了一个BROADCAST_INTENT_MSG类型的消息,BroadcastQueue接收到消息后会调用processNextBroadcast()方法。

2. BroadcastQueue.processNextBroadcast()

final void processNextBroadcast(boolean fromMsg) {
//处理普通并行广播
//处理有序串行广播
//处理下条有序广播
}


这里只分析普通并行广播的处理:

while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
//遍历mParalleBroadcasts,并将广播发送给他们的接收者
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
//分发给已经注册的广播接收者
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
//添加到历史记录
addBroadcastToHistoryLocked(r);
}


3. BroadcastQueue.deliverToRegisteredReceiverLocked()

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
boolean skip = false;
//权限认证
try {
if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
//省略部分代码
} else {
//处理广播
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
}
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}
} catch (RemoteException e) {
}
}


4. BroadcastQueue.performReceiveLocked()

void performReceiveLocked(//省略参数) throws RemoteException {
//通过binder异步机制,向receiver发送intent
if (app != null) {
if (app.thread != null) {
//跨进程调用ApplicationThread的scheduleRegisteredReceiver()方法
try {
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
} catch (RemoteException ex) {

synchronized (mService) {
app.scheduleCrash("can't deliver broadcast");
}
throw ex;
}
} else {
//应用进程死亡,Receiver不存在.
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}


5. Application.scheduleRegisteredReceiver()

public void scheduleRegisteredReceiver(//省略参数) throws RemoteException {
//更新进程状态
updateProcessState(processState, false);
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}


6. InnerReceiver.performReceive()

public void performReceive(//省略参数) {
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
//省略部分代码
}
}


7. ReceiverDispatcher.performReceive()

public void performReceive(//省略参数) {
//创建Args对象
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
//通过mActivityThread的post方法来执行Args中的逻辑,这会调用Args中的run()方法
if (intent == null || !mActivityThread.post(args)) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManagerNative.getDefault();
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing sync broadcast to " + mReceiver);
args.sendFinished(mgr);
}
}
}


8. Args.run()

public void run() {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
try {
//获取mReceiver的类加载器
ClassLoader cl =  mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
//回调receiver.onReceive()方法
receiver.onReceive(mContext, intent);
} catch (Exception e) {

}

if (receiver.getPendingResult() != null) {
finish();
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}


到这里回调了receiver.onReceive()方法之后,一条广播就完成了,当然后面会执行finish()方法,里面会执行处理下一条广播的逻辑,这里就不深究了。

七、接收广播总结

接收过程:

根据广播类型,进行分类处理;

遍历广播列表,循环发送给他们的接收者;

回调receiver.onReceive()方法,完成广播处理。

广播注册、发送、接收过程分析完了,这里为了尽量简化只采用了一条普通广播的线来走这个流程,如果是把每种类型广播都分析清楚还是有点复杂的。当然我们只是想揪出一条思路,学习思维,不要深入其中无法自拔。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android broadcast