本篇文章的目录
1、广播数据结构分析
2、线程的切换
3、processNextBroadcast分析
- 3.1、处理并行广播
- 3.2、处理Pending广播
- 3.3、处理有序广播
- 3.4、获取下一条广播
- 3.5、检查是否是动态广播
- 3.6、检查是否是静态广播
- 3.7、启动进程,处理未发送的静态广播
4、动态广播receiver处理
5、静态广播receiver处理
先了解一下广播的数据结构,然后在分析广播的处理过程。建议看本文,需要先看前面两篇文章
Android源码解析—广播的注册过程
Android源码解析—广播的处理过程
1、广播数据结构分析
final class BroadcastRecord extends Binder {
final Intent intent;
final ComponentName targetComp;
final ProcessRecord callerApp;
final String[] requiredPermissions;
final List receivers;
IIntentReceiver resultTo;
long enqueueClockTime;
long dispatchTime;
long dispatchClockTime;
long receiverTime;
long finishTime;
int nextReceiver;
IBinder receiver;
int state;
int anrCount;
ProcessRecord curApp;
ComponentName curComponent;
ActivityInfo curReceiver;
}
比较重要的数据成员有receivers,存储的都是广播接收器,callerApp是广播调用者进程,还要注意四个时间点,有入队列,分发,接收,完成,另外动态广播节点用BroadcastFilter描述,静态的用ResolveInfo描述。
2、线程的切换
上篇说到不管是有序广播、无序广播还是粘性广播最终都是调用scheduleBroadcastsLocked处理的。那么scheduleBroadcastsLocked做了什么?
public void scheduleBroadcastsLocked() {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
+ mQueueName + "]: current="
+ mBroadcastsScheduled);
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
mHandler是BroadcastQueue的成员变量,定义如下
final BroadcastHandler mHandler;
它在BroadcastQueue构造函数中初始化
BroadcastQueue(ActivityManagerService service, Handler handler,
String name, long timeoutPeriod, boolean allowDelayBehindServices) {
mService = service;
mHandler = new BroadcastHandler(handler.getLooper());
mQueueName = name;
mTimeoutPeriod = timeoutPeriod;
mDelayBehindServices = allowDelayBehindServices;
}
参数中的handler是AMS中的MainHandler,所以BroadcastHandler采用的是ActivityManager线程的Looper,所以通过上面发送一个BROADCAST_INTENT_MSG消息,现在由system_server的binder线程切换到system_server的ActivityManager线程中。
private final class BroadcastHandler extends Handler {
public BroadcastHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
if (DEBUG_BROADCAST) Slog.v(
TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
case SCHEDULE_TEMP_WHITELIST_MSG: {
DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController;
if (dic != null) {
dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1),
msg.arg2, true, (String)msg.obj);
}
} break;
}
}
}
所以现在重点分析processNextBroadcast方法。
3、processNextBroadcast分析
processNextBroadcast方法的代码跟broadcastIntentLocked方法一样,也是很长,所以分段来分析。
3.1、处理并行广播
mService.updateCpuStats();
if (fromMsg) {
mBroadcastsScheduled = false;
}
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
+ mQueueName + "] " + r);
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Delivering non-ordered on [" + mQueueName + "] to registered "
+ target + ": " + r);
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
addBroadcastToHistoryLocked(r);
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
+ mQueueName + "] " + r);
}
3.2、处理Pending广播
如果一个广播在发送的时候,进程还没有启动起来,那么会将它存在mPendingBroadcast中。由于动态广播是不会保证一定能够收到的,所以mPendingBroadcast是用来描述一个正在等待静态注册的目标广播接收者启动的广播。
if (mPendingBroadcast != null) {
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
"processNextBroadcast [" + mQueueName + "]: waiting for "
+ mPendingBroadcast.curApp);
boolean isDead;
synchronized (mService.mPidsSelfLocked) {
ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);
isDead = proc == null || proc.crashing;
}
如果这个应用程序进程还活着,就会继续等待,否则就不等了
if (!isDead) {
return;
} else {
Slog.w(TAG, "pending app ["
+ mQueueName + "]" + mPendingBroadcast.curApp
+ " died before responding to broadcast");
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null;
}
}
boolean looped = false;
3.3、处理有序广播
有序广播是一个接着一个处理的,并且还可以拦截,
do {
if (mOrderedBroadcasts.size() == 0) {
mService.scheduleAppGcsLocked();
if (looped) {
mService.updateOomAdjLocked();
}
return;
}
r = mOrderedBroadcasts.get(0);
boolean forceReceive = false;
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
if (mService.mProcessesReady && r.dispatchTime > 0) {
long now = SystemClock.uptimeMillis();
if ((numReceivers > 0) &&
(now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
Slog.w(TAG, "Hung broadcast ["
+ mQueueName + "] discarded after timeout failure:"
+ " now=" + now
+ " dispatchTime=" + r.dispatchTime
+ " startTime=" + r.receiverTime
+ " intent=" + r.intent
+ " numReceivers=" + numReceivers
+ " nextReceiver=" + r.nextReceiver
+ " state=" + r.state);
broadcastTimeoutLocked(false);
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
}
if (r.state != BroadcastRecord.IDLE) {
if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
"processNextBroadcast("
+ mQueueName + ") called when not idle (state="
+ r.state + ")");
return;
}
广播是否已经被拦截了,四:广播是否已经被强制结束了
if (r.receivers == null || r.nextReceiver >= numReceivers
|| r.resultAbort || forceReceive) {
if (r.resultTo != null) {
try {
if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
"Finishing broadcast [" + mQueueName + "] "
+ r.intent.getAction() + " app=" + r.callerApp);
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;
Slog.w(TAG, "Failure ["
+ mQueueName + "] sending broadcast result of "
+ r.intent, e);
}
}
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
cancelBroadcastTimeoutLocked();
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
"Finished with ordered broadcast " + r);
addBroadcastToHistoryLocked(r);
if (r.intent.getComponent() == null && r.intent.getPackage() == null
&& (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
}
mOrderedBroadcasts.remove(0);
r = null;
looped = true;
continue;
}
} while (r == null);
3.4、获取下一条广播
//通过上面的循环,r就有值了,获取下一条广播
int recIdx = r.nextReceiver++
// Keep track of when this receiver started, and make sure there
// is a timeout message pending to kill it if need be.
r.receiverTime = SystemClock.uptimeMillis()
if (recIdx == 0) {
r.dispatchTime = r.receiverTime
r.dispatchClockTime = System.currentTimeMillis()
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
+ mQueueName + "] " + r)
}
if (! mPendingBroadcastTimeoutMessage) {
long timeoutTime = r.receiverTime + mTimeoutPeriod
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Submitting BROADCAST_TIMEOUT_MSG ["
+ mQueueName + "] for " + r + " at " + timeoutTime)
setBroadcastTimeoutLocked(timeoutTime)
}ComponentName component
final BroadcastOptions brOptions = r.options
final Object nextReceiver = r.receivers.get(recIdx)
```
####3.5、检查是否是动态广播
//检查是否是动态广播
if (nextReceiver instanceof BroadcastFilter) {
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
“Delivering ordered [”
+ mQueueName + “] to registered ”
+ filter + “: ” + r);
//动态注册的广播给deliverToRegisteredReceiverLocked处理
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
//判断是否是无序广播
if (r.receiver == null || !r.ordered) {
// The receiver has already finished, so schedule to
// process the next one.
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, “Quick finishing [”
+ mQueueName + “]: ordered=”
+ r.ordered + ” receiver=” + r.receiver);
//将 r.state设置为IDLE,表示不需要等待它的前一个目标广播接收者处理完成一个广播,
// 就可以将该广播继续发送给它的下一个目标广播接收者处理
r.state = BroadcastRecord.IDLE;
//执行下一个广播,内部也是发送消息
scheduleBroadcastsLocked();
} else {
….
}
//有序广播一次只处理一个,直接返回就行
return;
}
####3.6、检查是否是静态广播
//如果上面没有return,那么肯定是静态注册的广播,静态注册注册的广播节点是ResolveInfo
ResolveInfo info = (ResolveInfo)nextReceiver;
//这个ComponentName会一直传递到ActivityThread,用来反射new广播接收者对象的
ComponentName component = new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
//很多的条件判断,skip不满足就为true
boolean skip = false;
…….
String targetProcess = info.activityInfo.processName;
ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
info.activityInfo.applicationInfo.uid, false);
if (skip) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Skipping delivery of ordered [" + mQueueName + "] "
+ r + " for whatever reason");
r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
r.receiver = null;
r.curFilter = null;
//变成初始状态
r.state = BroadcastRecord.IDLE;
//执行下个广播
scheduleBroadcastsLocked();
return;
}
…….
//如果当前进程存在,调用processCurBroadcastLocked处理,静态广播都是走processCurBroadcastLocked处理的
if (app != null && app.thread != null) {
try {
app.addPackage(info.activityInfo.packageName,
info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
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.
}
//程序走到这里,说明进程不存在,那么调用startProcessLocked启动进程,
if ((r.curApp=mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
“broadcast”, r.curComponent,
(r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
== null) {
// Ah, this recipient is unavailable. Finish it if necessary,
// and mark the broadcast record as ready for the next.
Slog.w(TAG, “Unable to launch app ”
+ info.activityInfo.applicationInfo.packageName + “/”
+ info.activityInfo.applicationInfo.uid + ” 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;
}
//把当前的r存下来,方便下一次处理
mPendingBroadcast = r;
//设置当前的receiver的索引,用来表示将要启动的。
mPendingBroadcastRecvIndex = recIdx;
“`
3.7、启动进程,处理未发送的静态广播
当进程启动完成之后,会回调AMS的attachApplication,然后走到attachApplicationLocked。
“`
// Check if a next-broadcast receiver is in this process…
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
// If the app died trying to launch the receiver we declare it ‘bad’
Slog.wtf(TAG, “Exception thrown dispatching broadcasts in ” + app, e);
badApp = true;
}
}
// The app just attached; send any pending broadcasts that it should receive
boolean sendPendingBroadcastsLocked(ProcessRecord app) {
boolean didSomething = false;
for (BroadcastQueue queue : mBroadcastQueues) {
didSomething |= queue.sendPendingBroadcastsLocked(app);
}
return didSomething;
}
public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
boolean didSomething = false;
final BroadcastRecord br = mPendingBroadcast;
if (br != null && br.curApp.pid == app.pid) {
if (br.curApp != app) {
Slog.e(TAG, “App mismatch when sending pending broadcast to ”
+ app.processName + “, intended target is ” + br.curApp.processName);
return false;
}
try {
//目标进程已经成功启动了,那么mPendingBroadcast就可以赋值为null了
mPendingBroadcast = null;
//调用processCurBroadcastLocked处理广播
processCurBroadcastLocked(br, app);
didSomething = true;
} catch (Exception e) {
Slog.w(TAG, “Exception in new application when starting receiver ”
+ br.curComponent.flattenToShortString(), e);
logBroadcastReceiverDiscardLocked(br);
finishReceiverLocked(br, br.resultCode, br.resultData,
br.resultExtras, br.resultAbort, false);
scheduleBroadcastsLocked();
// We need to reset the state if we failed to start the receiver.
br.state = BroadcastRecord.IDLE;
throw new RuntimeException(e.getMessage());
}
}
return didSomething;
}
“`
看完上面的三个小节,到这里总结一下 processNextBroadcast()的代码逻辑:
- 如果是动态广播接收者(无序),会调用deliverToRegisteredReceiverLocked一次性处理,即遍历并行列表(mParallelBroadcasts)的每一个BroadcastRecord以及其中的receivers列表,是一个双重循环。
- 如果是静态广播接收者(有序),且对应进程已经创建,会调用processCurBroadcastLocked继续处理;
- 如果是静态广播接收者(有序),且对应进程尚未创建,会调用startProcessLocked创建进程,之后仍然会调用processCurBroadcastLocked继续处理。
4、动态广播receiver处理
上面主要分析了动态广播接收者和静态广播接收者该如何处理,现在先看动态广播是如何处理的。就是分析deliverToRegisteredReceiverLocked方法实现。
“`
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
boolean skip = false;
//权限判断, 检查发送者是否有权限,检查接收者是否有发送者所需的权限等等,
//此处省略,不符合的skip==true,下面就return。
….
if (skip) {
r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
return;
}
....
//只有有序广播才会进入这个分支
if (ordered) {
r.receiver = filter.receiverList.receiver.asBinder();
r.curFilter = filter;
filter.receiverList.curBroadcast = r;
r.state = BroadcastRecord.CALL_IN_RECEIVE;
if (filter.receiverList.app != null) {
// Bump hosting application to no longer be in background
// scheduling class. Note that we can't do that if there
// isn't an app... but we can only be in that case for
// things that directly call the IActivityManager API, which
// are already core system stuff so don't matter for this.
r.curApp = filter.receiverList.app;
filter.receiverList.app.curReceiver = r;
mService.updateOomAdjLocked(r.curApp);
}
}
try {
if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
"Delivering to " + filter + " : " + r);
if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
// Skip delivery if full backup in progress
// If it's an ordered broadcast, we need to continue to the next receiver.
if (ordered) {
skipReceiverLocked(r);
}
} else {
//处理广播,filter.receiverList.receiver对应的是客户端ReceiverDispatcher的Binder实体——InnerReceiver
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) {
....
}
}
“`
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
if (app != null) {
if (app.thread != null) {
try {
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
} catch (RemoteException ex) {
.....
}
} else {
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
updateProcessState(processState, false);
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}
终于走到客户端的ReceiverDispatcher(广播分发者)了,ReceiverDispatcher知道我们这个广播要分发给谁。此时正式由SystemServer进程回到客户端进程了。
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
......
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 = ActivityManagerNative.getDefault();
try {
if (extras != null) {
extras.setAllowFds(false);
}
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
可以看到我们调用ReceiverDispatcher中InnerReceiver的performReceive之后,紧接着在内部调用了ReceiverDispatcher的performReceive方法,再看ReceiverDispatcher的performReceive方法。
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
if (intent == null) {
Log.wtf(TAG, "Null intent received");
} else {
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
+ " seq=" + seq + " to " + mReceiver);
}
}
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);
}
}
}
上面的mActivityThread在第一篇文章说过,代表主线程,所以现在会执行args的run方法。
public void run() {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
if (ActivityThread.DEBUG_BROADCAST) {
int seq = mCurIntent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
+ " seq=" + seq + " to " + mReceiver);
Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
+ " mOrderedHint=" + ordered);
}
final IActivityManager mgr = ActivityManagerNative.getDefault();
final Intent intent = mCurIntent;
if (intent == null) {
Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched);
}
......
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
} catch (Exception e) {
.....
}
到此,deliverToRegisteredReceiverLocked是怎么处理动态广播就分析完毕了。总结一下主要流程
——|-BroadcastQueue.performReceiveLocked()
——|——-|-ActivityThread.ApplicationThread.scheduleRegisteredReceiver()
——|——-|——-|- ReceiverDispatcher.InnerReceiver.performReceive()
——|——-|——-|——-|-Handler.post(args)
——|——-|——-|——-|——-|-Args.run()
——|——-|——-|——-|——-|——-|-BroadcastReceiver.onReceive()
5、静态广播receiver处理
刚刚说了静态广播是processCurBroadcastLocked处理的
private final void processCurBroadcastLocked(BroadcastRecord r,
ProcessRecord app) throws RemoteException {
.....
r.receiver = app.thread.asBinder()
r.curApp = app
app.curReceiver = r
//更新进程状态
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER)
//更新内存
mService.updateLruProcessLocked(app, false, null)
//更新adj
mService.updateOomAdjLocked()
// Tell the application to launch this receiver.告诉客户端启动这个receiver
r.intent.setComponent(r.curComponent)
boolean started = false
try {
.....
//走到了ActivityThread中的ApplicationThread中对应的方法。
app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
app.repProcState)
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Process cur broadcast " + r + " DELIVERED for app " + app)
started = true
} finally {
.....
}
}
}
此时正式由SystemServer进程进入了客户端进程了
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
r.info = info;
r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
一样的套路,发送一个消息给主线程,进入对应的case,执行 handleReceiver((ReceiverData)msg.obj);
private void handleReceiver(ReceiverData data) {
// 这个最初就是在processNextBroadcast处理静态注册的ResolveInfo时,new的ComponentName。
String component = data.intent.getComponent().getClassName()
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo)
IActivityManager mgr = ActivityManagerNative.getDefault()
BroadcastReceiver receiver
try {
//反射出BroadcastReceiver
java.lang.ClassLoader cl = packageInfo.getClassLoader()
data.intent.setExtrasClassLoader(cl)
data.intent.prepareToEnterProcess()
data.setExtrasClassLoader(cl)
receiver = (BroadcastReceiver)cl.loadClass(component).newInstance()
} catch (Exception e) {
if (DEBUG_BROADCAST) Slog.i(TAG,
"Finishing failed broadcast to " + data.intent.getComponent())
data.sendFinished(mgr)
throw new RuntimeException(
"Unable to instantiate receiver " + component
+ ": " + e.toString(), e)
}
try {
Application app = packageInfo.makeApplication(false, mInstrumentation)
if (localLOGV) Slog.v(
TAG, "Performing receive of " + data.intent
+ ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + packageInfo.getPackageName()
+ ", comp=" + data.intent.getComponent().toShortString()
+ ", dir=" + packageInfo.getAppDir())
ContextImpl context = (ContextImpl)app.getBaseContext()
sCurrentBroadcastIntent.set(data.intent)
receiver.setPendingResult(data)
//这个和动态的不一样,静态的广播onReceive方法中的context是RestrictedContext
receiver.onReceive(context.getReceiverRestrictedContext(),
data.intent)
} catch (Exception e) {
if (DEBUG_BROADCAST) Slog.i(TAG,
"Finishing failed broadcast to " + data.intent.getComponent())
data.sendFinished(mgr)
if (!mInstrumentation.onException(receiver, e)) {
throw new RuntimeException(
"Unable to start receiver " + component
+ ": " + e.toString(), e)
}
} finally {
sCurrentBroadcastIntent.set(null)
}
if (receiver.getPendingResult() != null) {
data.finish()
}
}
到这总结一下静态广播接收者的处理流程,如下:
如果应用程序已经启动(app.thread != null)
——|-ActivityThread.ApplicationThread.scheduleReceiver()
——|——|- ActivityThread.handleReceiver()
——|——-|——-|- BroadcastReceiver.onReceive()
否则
——|-LoadedApk.ReceiverDispatcher.IntentReceiver.performReceive()
——|——-|-LoadedApk.ReceiverDispatcher.performReceiver()
——|——-|——-|- LoadedApk.ReceiverDispatcher.Args.run()
——|——-|——-|——-|-BroadcastReceiver.onReceive()
至此广播的处理过程就结束了,下篇写一下广播细节,加深理解,比如广播有序是怎么保证的?怎么实现广播拦截处理的?广播超时是怎么处理的?onReceive方法中可以在发送广播吗?registerReceiver方法发返回值有什么用?粘性广播等等
作者:u013263323 发表于2017/7/24 11:54:01
原文链接