Service ANR:
啓動Service 的時候,會調用到ActiveServices 類的 realStartServiceLocked方法。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//發送延遲消息
bumpServiceExecutingLocked(r, execInFg, "create");
}
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
boolean timeoutNeeded = true;
long now = SystemClock.uptimeMillis();
if (r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if (timeoutNeeded && r.app.executingServices.size() == 1) {
scheduleServiceTimeoutLocked(r.app);
}
}
} else if (r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
if (timeoutNeeded) {
scheduleServiceTimeoutLocked(r.app);
}
}
r.executeFg |= fg;
r.executeNesting++;
r.executingStart = now;
}
繼續調用scheduleServiceTimeoutLocked
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageDelayed(msg,
proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
可以看到,裏面拿到AtivityManagerService 的 Mainhandler 發送一個延期消息。
當Service 啓動之後,就會移除掉消息。(ActiveServices)見下面:
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
boolean finishing) {
if (r.executeNesting <= 0) {
if (r.app != null) {
if (r.app.executingServices.size() == 0) {
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
BroadcastReceiver ANR:
當處理廣播的時候,會走到下面的processNextBroadcastLocked 方法:
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
BroadcastRecord r;
// First, deliver any non-serialized broadcasts right away.
while (mParallelBroadcasts.size() > 0) {
if (mService.mProcessesReady && r.dispatchTime > 0) {
long now = SystemClock.uptimeMillis();
if ((numReceivers > 0) &&
(now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
broadcastTimeoutLocked(false); // forcibly finish this broadcast
forceReceive = true;
r.state = BroadcastRecord.IDLE;
cancelBroadcastTimeoutLocked();
}
}
broadcastTimeoutLocked 裏面會調用setBroadcastTimeoutLocked 方法,設置超時時間。
setBroadcastTimeoutLocked:
final void setBroadcastTimeoutLocked(long timeoutTime) {
if (! mPendingBroadcastTimeoutMessage) {
Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
mHandler.sendMessageAtTime(msg, timeoutTime);
mPendingBroadcastTimeoutMessage = true;
}
}
BroadcastHandler 是自己的Handler,但是Looper 是ActivityManagerService 的 MainHandler 的Looper.
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;
}
}
}
處理ANR:
final void broadcastTimeoutLocked(boolean fromMsg) {
if (!debugging && anrMessage != null) {
// Post the ANR to the handler since we do not want to process ANRs while
// potentially holding our lock.
mHandler.post(new AppNotResponding(app, anrMessage));
}
}
處理ANR:
private final class AppNotResponding implements Runnable {
private final ProcessRecord mApp;
private final String mAnnotation;
public AppNotResponding(ProcessRecord app, String annotation) {
mApp = app;
mAnnotation = annotation;
}
@Override
public void run() {
mService.mAppErrors.appNotResponding(mApp, null, null, false, mAnnotation);
}
}
ContentProvider ANR:
ContentProvider Timeout是位於”ActivityManager”線程中的AMS.MainHandler收到CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息時觸發。
ContentProvider 超時爲CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10s. 這個跟前面的Service和BroadcastQueue完全不同, 由Provider進程啓動過程相關.
ContentProvider 是在app 啓動的時候,初始化的。初始話的時候,會發一條延遲消息,CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
當發佈成功之後,就會移除掉這條消息。
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
if (wasInLaunchingProviders) {
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
}
}
}
https://www.jianshu.com/p/1c827675f457