android之基础学习攻克

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执行命令时是否超时,同时对进程管理也有一定的影响。

unbouned service start时序图

Unbounded start Service uml.png

参考: Android 7.0 ActivityManagerService(6) Service相关流程分析

上一篇下一篇

猜你喜欢

热点阅读