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

android ANR源码分析 --- 之二

2017-10-31 20:11 381 查看

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android ANR 源码分析