• 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;
    		}
        }
    }
    
  • 相关阅读:
    PS图层中如何快速找到想要的图层
    知识点手记二
    IE6兼容
    Hack、自适应、针对浏览器写样式随手笔记
    汇编语言实验三
    汇编语言实验二
    汇编语言实验一
    寄存器与代码段
    java.nio.Buffer源码阅读
    汇编语言初探
  • 原文地址:https://www.cnblogs.com/yongfengnice/p/14822913.html
Copyright © 2020-2023  润新知