2, BroadcastQueue Timeout
触发时机: BroadcastQueue中的mHandler收到BROADCAST_TIMEOUT_MSG消息时触发.
在广播的流程中,匹配广播之后,最后AMS会调用BroadcastQueue的processNextBroadcast方法进行处理。processNextBroadcast方法主要逻辑如下,
1,首先处理一般广播(并行广播)
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);
}
2,处理当前的有序广播,
获取广播的接受者,
r = mOrderedBroadcasts.get(0);
boolean forceReceive = false;
•••
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
然后调用broadcastTimeoutLocked方法发送消息,
broadcastTimeoutLocked(false);
广播处理,
performReceiveLocked(r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false, r.userId);
如果处理成功,就删除消息,
cancelBroadcastTimeoutLocked();
2.1 发送消息
发送消息调用的是BroadcastQueue的broadcastTimeoutLocked方法, broadcastTimeoutLocked方法主要根据不同情况分别
调用setBroadcastTimeoutLocked方法处理,
setBroadcastTimeoutLocked(timeoutTime);
对于前台广播,超时为10s;对于后台广播,超时为60s
AMS时间定义如下,
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
setBroadcastTimeoutLocked方法如下,
Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
mHandler.sendMessageAtTime(msg, timeoutTime);
mPendingBroadcastTimeoutMessage = true;
发送BROADCAST_TIMEOUT_MSG消息。
2.2 删除消息
在前面已论述到,删除消息调用的是BroadcastQueue的cancelBroadcastTimeoutLocked方法,
该方法如下,
mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this);
mPendingBroadcastTimeoutMessage = false;
2.3 处理消息
BroadcastQueue的内部类BroadcastHandler的handleMessage方法对BROADCAST_TIMEOUT_MSG消息处理如下,
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
在broadcastTimeoutLocked方法中,首先获取anrMessage 字符串,
anrMessage = "Broadcast of " + r.intent.toString();
然后调用内部线程类AppNotResponding进行处理,
mHandler.post(new AppNotResponding(app, anrMessage));
AppNotResponding的run方法如下,
mService.appNotResponding(mApp, null, null, false, mAnnotation);
因此,最后还是调用AMS的appNotResponding方法。
3, ContentProvider Timeout
触发时机:AMS的mHandler收到CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息时触发。
3.1发送消息
在创建进程之后,AMS的attachApplicationLocked方法首先会加载ContentProvider,
因此,在这个过程中,
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
CONTENT_PROVIDER_PUBLISH_TIMEOUT为10s,定义如下,
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
3.2删除消息
安装完成ContentProvider,客户端就会调AMS的publishContentProviders方法通知Provider安装完成。
在AMS的publishContentProviders方法中,会删除该消息,
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
3.3 处理消息
AMS的内部类MainHandler的handleMessage对CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息处理如下,
processContentProviderPublishTimedOutLocked(app);
processContentProviderPublishTimedOutLocked方法如下,
private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
cleanupAppInLaunchingProvidersLocked(app, true); //[见4.3.3]
removeProcessLocked(app, false, true, "timeout publishing content providers");
}
removeProcessLocked方法最后会杀死该进程,
app.kill(reason, true);