Service相关流程学习-Unbouned Start Ser
2018-11-25 本文已影响0人
weiinter105
重新回到realStartServiceLocked,分析真正启动Service的正常流程
ActiveServices#bumpServiceExecutingLocked
1875 private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
1876 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING "
1877 + why + " of " + r + " in app " + r.app);
1878 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING "
1879 + why + " of " + r.shortName);
1886 long now = SystemClock.uptimeMillis();
1887 if (r.executeNesting == 0) { //executeNesting用于记录Service待处理的请求数量
//处理第一个命令时,即初次启动Service时
1888 r.executeFg = fg;
1889 ServiceState stracker = r.getTracker();
1890 if (stracker != null) {
//记录时间
1891 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
1892 }
1893 if (r.app != null) { //更新进程ProcessRecord中关于Service的记录
1894 r.app.executingServices.add(r);
1895 r.app.execServicesFg |= fg;
1896 if (r.app.executingServices.size() == 1) {
//executingServices正在执行的Service
//设置启动Service超时的时间
//即Service初次启动时,如果进程中只有这一个Service
//那么一旦启动超时,将触发AMS发送ANR
1897 scheduleServiceTimeoutLocked(r.app); //发送SERVICE_TIMEOUT_MSG消息(sendMessageDelayed,先入队,等到后面一定时间触发执行),如果没被按时remove,那么就会触发ANR
1898 }
1899 }
1900 } else if (r.app != null && fg && !r.app.execServicesFg) { //前台进程向后台服务发送命令时,也会设置超时时间,一旦超时,也会ANR
//发送一次后,该值变为true,相当与变成前台服务了
1901 r.app.execServicesFg = true;
1902 scheduleServiceTimeoutLocked(r.app);
1903 }
1904 r.executeFg |= fg;
1905 r.executeNesting++; //每处理一个命令,executeNesting均会+1,会在后被面serviceDoneExecutingLocked清理掉
1906 r.executingStart = now; // start time of last execute request. 用于记录上次命令的执行时间,与ANR的判断有关
1907 }
3563 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
//proc当前服务所在进程
3564 if (proc.executingServices.size() == 0 || proc.thread == null) {
3565 return;
3566 }
3567 Message msg = mAm.mHandler.obtainMessage(
3568 ActivityManagerService.SERVICE_TIMEOUT_MSG);
3569 msg.obj = proc;
3575 mAm.mHandler.sendMessageDelayed(msg,
3576 proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT); //发送消息,并根据前后台服务选择相应时间触发
3577 }
消息触发最终会走到这里,触发ANR逻辑
3488 void serviceTimeout(ProcessRecord proc) {
3489 String anrMessage = null;
3490
3491 synchronized(mAm) {
3492 if (proc.executingServices.size() == 0 || proc.thread == null) {
3493 return;
3494 }
3495 final long now = SystemClock.uptimeMillis();
3496 final long maxTime = now -
3497 (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
3498 ServiceRecord timeout = null;
3499 long nextTime = 0;
3500 for (int i=proc.executingServices.size()-1; i>=0; i--) {
3501 ServiceRecord sr = proc.executingServices.valueAt(i);
3502 if (sr.executingStart < maxTime) { //上一次Service处理的命令时间距离现在时间过长,触发ANR,也就是本次Service执行命令过长会触发ANR
3503 timeout = sr;
3504 break;
3505 }
3506 if (sr.executingStart > nextTime) {
//nextTime的值,等于所有待处理Service命令,启动时间的最大值
//用于触发下一次超时处理
3507 nextTime = sr.executingStart;
3508 }
3509 }
3510 if (timeout != null && mAm.mLruProcesses.contains(proc)) {
3511 Slog.w(TAG, "Timeout executing service: " + timeout);
3512 StringWriter sw = new StringWriter();
3513 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
3514 pw.println(timeout);
3515 timeout.dump(pw, " ");
3516 pw.close();
3517 mLastAnrDump = sw.toString();
3518 mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
3519 mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
3520 anrMessage = "executing service " + timeout.shortName;
3521 } else {
3522 Message msg = mAm.mHandler.obtainMessage(
3523 ActivityManagerService.SERVICE_TIMEOUT_MSG);
3524 msg.obj = proc;
3525 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
3526 ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT)); //触发下一次超时检查机制
3527 }
3528 }
3529
3530 if (anrMessage != null) {
3531 mAm.mAppErrors.appNotResponding(proc, null, null, false, anrMessage); //ANR流程
3532 }
3533 }
定时发送SERVICE_TIMEOUT_MSG,本次Service执行请求的时间超时则会出现ANR
ActivityThread#scheduleCreateService
857 public final void scheduleCreateService(IBinder token,
858 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
859 updateProcessState(processState, false);
860 CreateServiceData s = new CreateServiceData();
861 s.token = token;
862 s.info = info;
863 s.compatInfo = compatInfo;
864
865 sendMessage(H.CREATE_SERVICE, s);
866 }
1701 case CREATE_SERVICE:
1702 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
1703 handleCreateService((CreateServiceData)msg.obj);
1704 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1705 break;
ActivityThread#handleCreateService
3347 private void handleCreateService(CreateServiceData data) {
3348 // If we are getting ready to gc after going to the background, well
3349 // we are back active so skip it.
3350 unscheduleGcIdler(); //暂时放弃gc
3351
3352 LoadedApk packageInfo = getPackageInfoNoCheck(
3353 data.info.applicationInfo, data.compatInfo);
3354 Service service = null;
3355 try {
3356 java.lang.ClassLoader cl = packageInfo.getClassLoader();
3357 service = (Service) cl.loadClass(data.info.name).newInstance(); //通过反射创建出一个实例
3358 } catch (Exception e) {
3359 if (!mInstrumentation.onException(service, e)) {
3360 throw new RuntimeException(
3361 "Unable to instantiate service " + data.info.name
3362 + ": " + e.toString(), e);
3363 }
3364 }
3365
3366 try {
3367 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
3368
3369 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3370 context.setOuterContext(service);
3371
3372 Application app = packageInfo.makeApplication(false, mInstrumentation);
//此时Service才算运行在Android环境中了
//此处传递的this是ActivityThread,这就是大家常说的:service也是运行在主线程中的原因
//因此在service中执行耗时操作,最好也利用HandlerThread,否则会造成ANR
//例如ConnectivityService、NetworkManagementService都是这么干的
3373 service.attach(context, this, data.info.name, data.token, app,
3374 ActivityManager.getService());
3375 service.onCreate();
3376 mServices.put(data.token, service); //ServiceRecord和其对应的Service实例
//mServices中存储了ActivityThread中运行的服务
//key值为Service对应的IBinder,是从Service对应的ServiceRecord中取出的
3377 try {
//通知AMS service启动成功,进行取消超时消息等操作,做收尾工作
3378 ActivityManager.getService().serviceDoneExecuting(
3379 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3380 } catch (RemoteException e) {
3381 throw e.rethrowFromSystemServer();
3382 }
3383 } catch (Exception e) {
3384 if (!mInstrumentation.onException(service, e)) {
3385 throw new RuntimeException(
3386 "Unable to create service " + data.info.name
3387 + ": " + e.toString(), e);
3388 }
3389 }
3390 }
调用serviceDoneExecuting传的type为:
199 /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
200 public static final int SERVICE_DONE_EXECUTING_ANON = 0;
没有针对type做特殊处理,直接调用3参数serviceDoneExecuting
对于executeNesting这个参数+1,-1是对应的,create时+1,create完成时-1;start时(向服务端传参数的过程)+1,最后调用serviceDoneExecuting又会-1;总之一一对应;
Service#attach
attach为创建的Service实例初始化一些参数
757 public final void attach(
758 Context context,
759 ActivityThread thread, String className, IBinder token,
760 Application application, Object activityManager) {
761 attachBaseContext(context);
762 mThread = thread; // NOTE: unused - remove?
763 mClassName = className;
764 mToken = token;
765 mApplication = application;
766 mActivityManager = (IActivityManager)activityManager;
767 mStartCompatibility = getApplicationInfo().targetSdkVersion
768 < Build.VERSION_CODES.ECLAIR;
769 }
ActiveServices#sendServiceArgsLocked
向创建的Service实例发送参数
2451 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
2452 boolean oomAdjusted) throws TransactionTooLargeException {
2453 final int N = r.pendingStarts.size();
2454 if (N == 0) {
2455 return;
2456 }
2457
2458 ArrayList<ServiceStartArgs> args = new ArrayList<>();
2459
2460 while (r.pendingStarts.size() > 0) {
2461 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
2462 if (DEBUG_SERVICE) {
2463 Slog.v(TAG_SERVICE, "Sending arguments to: "
2464 + r + " " + r.intent + " args=" + si.intent);
2465 }
2466 if (si.intent == null && N > 1) {
2467 // If somehow we got a dummy null intent in the middle,
2468 // then skip it. DO NOT skip a null intent when it is
2469 // the only one in the list -- this is to support the
2470 // onStartCommand(null) case.
2471 continue;
2472 }
2473 si.deliveredTime = SystemClock.uptimeMillis();
2474 r.deliveredStarts.add(si);
2475 si.deliveryCount++;//记录StartItem发送时间和发送次数,StartItem包含startService时的Intent
2476 if (si.neededGrants != null) {
2477 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
2478 si.getUriPermissionsLocked());
2479 }
2480 mAm.grantEphemeralAccessLocked(r.userId, si.intent,
2481 r.appInfo.uid, UserHandle.getAppId(si.callingId));
2482 bumpServiceExecutingLocked(r, execInFg, "start");
2483 if (!oomAdjusted) {
2484 oomAdjusted = true;
2485 mAm.updateOomAdjLocked(r.app, true);
2486 }
2487 if (r.fgRequired && !r.fgWaiting) {
2488 if (!r.isForeground) { //如果Service是前台服务,在O以上必须调用startForeground(一般在onStartCommand中)
2489 if (DEBUG_BACKGROUND_CHECK) {
2490 Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r);
2491 }
2492 scheduleServiceForegroundTransitionTimeoutLocked(r); //超时机制,SERVICE_FOREGROUND_TIMEOUT_MSG
2493 } else {
2494 if (DEBUG_BACKGROUND_CHECK) {
2495 Slog.i(TAG, "Service already foreground; no new timeout: " + r);
2496 }
2497 r.fgRequired = false;
2498 }
2499 }
2500 int flags = 0;
2501 if (si.deliveryCount > 1) {
2502 flags |= Service.START_FLAG_RETRY;
2503 }
2504 if (si.doneExecutingCount > 0) {
2505 flags |= Service.START_FLAG_REDELIVERY;
2506 }
/*
441 /**
442 * This flag is set in {@link #onStartCommand} if the Intent is a
443 * re-delivery of a previously delivered intent, because the service
444 * had previously returned {@link #START_REDELIVER_INTENT} but had been
445 * killed before calling {@link #stopSelf(int)} for that Intent.
446 */
//447 public static final int START_FLAG_REDELIVERY = 0x0001;
//这个flag用于onStartCommand返回START_REDELIVER_INTENT,用于Service被kill后startitem被复用的情况,
//在serviceDoneExecuting中doneExecutingCount++
2507 args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent)); //构建参数
2508 }
2509
2510 ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
2511 slice.setInlineCountLimit(4);
2512 Exception caughtException = null;
2513 try {
2514 r.app.thread.scheduleServiceArgs(r, slice); //调用scheduleServiceArgs
2515 } catch (TransactionTooLargeException e) { //传输的args太大了
2516 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large for " + args.size()
2517 + " args, first: " + args.get(0).args);
2518 Slog.w(TAG, "Failed delivering service starts", e);
2519 caughtException = e;
2520 } catch (RemoteException e) { //传参时Service所在进程挂了
2521 // Remote process gone... we'll let the normal cleanup take care of this.
2522 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
2523 Slog.w(TAG, "Failed delivering service starts", e);
2524 caughtException = e;
2525 } catch (Exception e) {
2526 Slog.w(TAG, "Unexpected exception", e);
2527 caughtException = e;
2528 }
2529
2530 if (caughtException != null) {//如果传参时发生了意外,那么就不能正常调用serviceDoneExecutingLocked进行收尾
2531 // Keep nesting count correct
2532 final boolean inDestroying = mDestroyingServices.contains(r);
2533 for (int i = 0; i < args.size(); i++) {
2534 serviceDoneExecutingLocked(r, inDestroying, inDestroying); //手动调用
2535 }
2536 if (caughtException instanceof TransactionTooLargeException) {
2537 throw (TransactionTooLargeException)caughtException;
2538 }
2539 }
2540 }
前台服务未调用startForeground的超时机制
3539 void serviceForegroundTimeout(ServiceRecord r) {
3540 ProcessRecord app;
3541 synchronized (mAm) {
3542 if (!r.fgRequired || r.destroying) {
3543 return;
3544 }
3545
3546 if (DEBUG_BACKGROUND_CHECK) {
3547 Slog.i(TAG, "Service foreground-required timeout for " + r);
3548 }
3549 app = r.app;
3550 r.fgWaiting = false;
3551 stopServiceLocked(r);
3552 }
3553
3554 if (app != null) {
3555 mAm.mAppErrors.appNotResponding(app, null, null, false,
3556 "Context.startForegroundService() did not then call Service.startForeground(): "
3557 + r);
3558 }
3559 }
673 /**
674 * If your service is started (running through {@link Context#startService(Intent)}), then
675 * also make this service run in the foreground, supplying the ongoing
676 * notification to be shown to the user while in this state.
677 * By default started services are background, meaning that their process won't be given
678 * foreground CPU scheduling (unless something else in that process is foreground) and,
679 * if the system needs to kill them to reclaim more memory (such as to display a large page in a
680 * web browser), they can be killed without too much harm. You use
681 * {@link #startForeground} if killing your service would be disruptive to the user, such as
682 * if your service is performing background music playback, so the user
683 * would notice if their music stopped playing.
684 *
685 * <p>Note that calling this method does <em>not</em> put the service in the started state
686 * itself, even though the name sounds like it. You must always call
687 * {@link #startService(Intent)} first to tell the system it should keep the service running,
688 * and then use this method to tell it to keep it running harder.</p>
689 *
690 * @param id The identifier for this notification as per
691 * {@link NotificationManager#notify(int, Notification)
692 * NotificationManager.notify(int, Notification)}; must not be 0.
693 * @param notification The Notification to be displayed.
694 *
695 * @see #stopForeground(boolean)
696 */
697 public final void startForeground(int id, Notification notification) {
698 try {
699 mActivityManager.setServiceForeground(
700 new ComponentName(this, mClassName), mToken, id,
701 notification, 0);
702 } catch (RemoteException ex) {
703 }
704 }
ActivityThread#scheduleServiceArgs
890 public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
891 List<ServiceStartArgs> list = args.getList();
892
893 for (int i = 0; i < list.size(); i++) {
894 ServiceStartArgs ssa = list.get(i);
895 ServiceArgsData s = new ServiceArgsData();
896 s.token = token;
897 s.taskRemoved = ssa.taskRemoved;
898 s.startId = ssa.startId;
899 s.flags = ssa.flags;
900 s.args = ssa.args;
901
902 sendMessage(H.SERVICE_ARGS, s);
903 }
904 }
1716 case SERVICE_ARGS:
1717 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
1718 handleServiceArgs((ServiceArgsData)msg.obj);
1719 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
ActivityThread#handleServiceArgs
3500 private void handleServiceArgs(ServiceArgsData data) {
3501 Service s = mServices.get(data.token); //通过ServiceRecord binder找到存储的Service实例,处理intent携带的内容,有返回值
3502 if (s != null) {
3503 try {
3504 if (data.args != null) {
3505 data.args.setExtrasClassLoader(s.getClassLoader());
3506 data.args.prepareToEnterProcess();
3507 }
3508 int res;
3509 if (!data.taskRemoved) {
3510 res = s.onStartCommand(data.args, data.flags, data.startId); //调用onStartCommand
3511 } else {
3512 s.onTaskRemoved(data.args); //调用onTaskRemoved,用于最近任务中划掉进程的Task时被调用
3513 res = Service.START_TASK_REMOVED_COMPLETE;
3514 }
//在通知AMS消息处理完成前,现完成本地等待处理的任务
//这里与启动BroadcastReceiver对应进程的情况相似
//进程可能是由于创建Service才被启动的,Service处理完毕后,AMS可能进行进程管理
//杀死Service对应进程,因此先确保工作做完
3516 if(!ActivityThreadInjector.isPersistent(mBoundApplication)) {
3517 QueuedWork.waitToFinish();
3518 }
3519 // QueuedWork.waitToFinish(); //等待本地QueuedWork处理完成,再进行清理工作 //参考https://jira.n.xiaomi.com/browse/MIUI-860168 QueuedWork类似任务队列
3521 try {
3522 ActivityManager.getService().serviceDoneExecuting(
3523 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); //通知AMS ServiceRecord相关结果,执行收尾工作,本次的type为SERVICE_DONE_EXECUTING_START,res为onStartCommand的返回值,描述了在系统的杀死事件中,系统应该如何继续这个服务的值,参考https://blog.csdn.net/taki_dsm/article/details/8865913 https://blog.csdn.net/zjws23786/article/details/51800929 return值由服务的需求自己指定
3524 } catch (RemoteException e) {
3525 throw e.rethrowFromSystemServer();
3526 }
3527 ensureJitEnabled();
3528 } catch (Exception e) {
3529 if (!mInstrumentation.onException(s, e)) {
3530 throw new RuntimeException(
3531 "Unable to start service " + s
3532 + " with " + data.args + ": " + e.toString(), e);
3533 }
3534 }
3535 }
3536 }
ActivityManagerService#serviceDoneExecutingLocked
19013 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
19014 synchronized(this) {
19015 if (!(token instanceof ServiceRecord)) {
19016 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
19017 throw new IllegalArgumentException("Invalid service token");
19018 }
19019 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
19020 }
19021 }
ActiveServices#serviceDoneExecuting
调用serviceDoneExecuting进行收尾工作
4参数serviceDoneExecuting最终也会调用3参数serviceDoneExecuting
2832 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
2833 boolean inDestroying = mDestroyingServices.contains(r);
2834 if (r != null) {
2835 if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
2836 // This is a call from a service start... take care of
2837 // book-keeping.
2838 r.callStart = true;
2839 switch (res) {
2840 case Service.START_STICKY_COMPATIBILITY:
2841 case Service.START_STICKY: {
2842 // We are done with the associated start arguments.
2843 r.findDeliveredStart(startId, true);
2844 // Don't stop if killed.
2845 r.stopIfKilled = false; //设定这个值,作用:为false时Service所在进程被kill时会重启
2846 break;
2847 }
2848 case Service.START_NOT_STICKY: {
2849 // We are done with the associated start arguments.
2850 r.findDeliveredStart(startId, true);
2851 if (r.getLastStartId() == startId) {
2852 // There is no more work, and this service
2853 // doesn't want to hang around if killed.
2854 r.stopIfKilled = true; //被kill后不再重启Service
2855 }
2856 break;
2857 }
2858 case Service.START_REDELIVER_INTENT: {
2859 // We'll keep this item until they explicitly
2860 // call stop for it, but keep track of the fact
2861 // that it was delivered.
2862 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
2863 if (si != null) {
2864 si.deliveryCount = 0;
2865 si.doneExecutingCount++;
2866 // Don't stop if killed.
2867 r.stopIfKilled = true;//重启Service并恢复上一个startItem,即上一个startService请求,适用于下载的断点续传
2868 }
2869 break;
2870 }
2871 case Service.START_TASK_REMOVED_COMPLETE: {
2872 // Special processing for onTaskRemoved(). Don't
2873 // impact normal onStartCommand() processing.
2874 r.findDeliveredStart(startId, true);
2875 break;
2876 }
2877 default:
2878 throw new IllegalArgumentException(
2879 "Unknown service start result: " + res);
2880 }
2881 if (res == Service.START_STICKY_COMPATIBILITY) {
2882 r.callStart = false;
2883 }
2884 } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
2885 // This is the final call from destroying the service... we should
2886 // actually be getting rid of the service at this point. Do some
2887 // validation of its state, and ensure it will be fully removed.
2888 if (!inDestroying) { //inDestroying调表进程正在被销毁
2889 // Not sure what else to do with this... if it is not actually in the
2890 // destroying list, we don't need to make sure to remove it from it.
2891 // If the app is null, then it was probably removed because the process died,
2892 // otherwise wtf
2893 if (r.app != null) {
2894 Slog.w(TAG, "Service done with onDestroy, but not inDestroying: "
2895 + r + ", app=" + r.app);
2896 }
2897 } else if (r.executeNesting != 1) {
2898 Slog.w(TAG, "Service done with onDestroy, but executeNesting="
2899 + r.executeNesting + ": " + r);
2900 // Fake it to keep from ANR due to orphaned entry.
2901 r.executeNesting = 1;
2902 }
2903 }
2904 final long origId = Binder.clearCallingIdentity();
2905 serviceDoneExecutingLocked(r, inDestroying, inDestroying);//调用3参数serviceDoneExecutingLocked
2906 Binder.restoreCallingIdentity(origId);
2907 } else {
2908 Slog.w(TAG, "Done executing unknown service from pid "
2909 + Binder.getCallingPid());
2910 }
2911 }
3参数
2924 private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
2925 boolean finishing) {
2926 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING " + r
2927 + ": nesting=" + r.executeNesting
2928 + ", inDestroying=" + inDestroying + ", app=" + r.app);
2929 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
2930 "<<< DONE EXECUTING " + r.shortName);
2931 r.executeNesting--;//ServiceRecord的一个命令执行完毕,executeNesting -1
//这些操作与前面提过的bumpServiceExecutingLocked函数,一一对应
2932 if (r.executeNesting <= 0) {//所有命令执行完毕
2933 if (r.app != null) {
2934 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
2935 "Nesting at 0 of " + r.shortName);
2936 r.app.execServicesFg = false;
2937 r.app.executingServices.remove(r);//ServiceRecord被从executingServices移除,处理超时消息时,不会处理该Service
2938 if (r.app.executingServices.size() == 0) {
2939 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
2940 "No more executingServices of " + r.shortName);
//整个进程所有的Service命令均处理完毕 移除timeout消息
看起只要按时return就不算超时,可以在onStartCommand逻辑中另开线程进行耗时操作,或者IntentService
2941 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
2942 } else if (r.executeFg) {
2943 // Need to re-evaluate whether the app still needs to be in the foreground.
2944 for (int i=r.app.executingServices.size()-1; i>=0; i--) {
2945 if (r.app.executingServices.valueAt(i).executeFg) {
2946 r.app.execServicesFg = true;//有一个Service是前台服务,则app仍是前台的
2947 break;
2948 }
2949 }
2950 }
2951 if (inDestroying) {
2952 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
2953 "doneExecuting remove destroying " + r);
2954 mDestroyingServices.remove(r);
2955 r.bindings.clear();
2956 }
2957 mAm.updateOomAdjLocked(r.app, true);
2958 }
2959 r.executeFg = false;
2960 if (r.tracker != null) {
2961 r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
2962 SystemClock.uptimeMillis());
2963 if (finishing) {
2964 r.tracker.clearCurrentOwner(r, false);
2965 r.tracker = null;
2966 }
2967 }
2968 if (finishing) {
2969 if (r.app != null && !r.app.persistent) {
//若Service结束,将其从进程对应的记录信息中移除
2970 r.app.services.remove(r);
2971 if (r.whitelistManager) {
2972 updateWhitelistManagerLocked(r.app);
2973 }
2974 }
2975 r.app = null;
2976 }
2977 }
2978 }
从上面的代码可以看出,这个serviceDoneExecutingLocked函数进行的扫尾工作,主要是为了更新ServiceRecord的相关信息。 这些信息将被用于判断Service执行命令时是否超时,同时对进程管理也有一定的影响。