Android源码分析启动Service服务超时ANR异常,到底多久会超时ANR看源代码一目了然

  • Android启动Service超时ANR异常源代码分析
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
   	...
    //其中Build.HW_TIMEOUT_MULTIPLIER一般为1
    // How long we wait for a service to finish executing.	--普通服务20秒
    static final int SERVICE_TIMEOUT = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;

    // How long we wait for a service to finish executing.
    static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;

    // How long the startForegroundService() grace period is to get around to
    // calling startForeground() before we ANR + stop it.	--前台服务10秒
    static final int SERVICE_START_FOREGROUND_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
    ...

    //1.发送ActivityManagerService.SERVICE_TIMEOUT_MSG延迟消息,时间到之前如果该消息被移除了
    //就不会出现ANR,否则时间到了执行该消息,抛出ANR异常。ANR原理是这样滴。。。
    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);
    }
    
    //3.服务启动完成后调用该方法,移除SERVICE_TIMEOUT_MSG消息就不会触发ANR异常。
    private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
            boolean finishing) {
        ...
      	if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
                            "No more executingServices of " + r.shortInstanceName);
          mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
          ...
    }
    
    //4.服务启动超时处理,就是我们常见的ANR报错
    void serviceTimeout(ProcessRecord proc) {
        ...
        if (timeout != null && mAm.mProcessList.mLruProcesses.contains(proc)) {//超时了
                Slog.w(TAG, "Timeout executing service: " + timeout);
                StringWriter sw = new StringWriter();
                PrintWriter pw = new FastPrintWriter(sw, false, 1024);
                pw.println(timeout);
                timeout.dump(pw, "    ");
                pw.close();
                mLastAnrDump = sw.toString();
                mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
                mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
                anrMessage = "executing service " + timeout.shortInstanceName;
            } else {//还没到时间,继续sendMessageAtTime消息
                Message msg = mAm.mHandler.obtainMessage(
                        ActivityManagerService.SERVICE_TIMEOUT_MSG);
                msg.obj = proc;
                mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
                        ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
            }
        ...
    }
}

frameworks/base/core/java/android/app/ActivityThread.java
//2.服务启动完成后调用该方法,进而调用上面的serviceDoneExecutingLocked方法
private void handleCreateService(CreateServiceData data) {
	...
	try {
		ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
	} catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
	}
    ...
}

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
//3.服务启动超时后,来到这里SERVICE_TIMEOUT_MSG分歧代码,最后执行mServices.serviceTimeout方法
final class MainHandler extends Handler {
	public MainHandler(Looper looper) {
		super(looper, null, true);
	}
	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {;
            case SERVICE_TIMEOUT_MSG: {
                mServices.serviceTimeout((ProcessRecord)msg.obj);
            } break;
		}
    }
}
原文地址:https://www.cnblogs.com/yongfengnice/p/14822913.html