Android -- 系统start Service流程简要分析

Android -- 系统start Service流程简要分析


Service是Android系统四大组件之一,它主要被用来在后台处理一些耗时操作,也会被设计成对Client提供业务的服务模块。Activity组件主要用来和用户进行交互,Service组件则可以在后台处理用户触发的一些请求操作,然后直接在Activity中展现请求结果。Activity和Service组件结合使用,能让我们设计出模块更清晰的应用。


Service有两种启动方式,一种是Start方式;一种是Bind方式。两种方式的使用细节可以参照之前转载的Service官方文档。此次,我们就先分析start Service的系统流程,Binde Service的分析会在下一篇讲述。


start Service,实际调用的是ContextImpl::startService()函数:

    @Override
    public ComponentName ContextImpl::startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }

    private ComponentName ContextImpl::startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread()/*AMS可以通过该ApplicationThread的Binder对象跟当前的应用进程通信*/, service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());//进入AMS::startService()
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
参数mMainThread指向启动该服务的应用进程,参数intent中一般会指定Service的class信息,或者服务的类型全限定名称。之后,实际调用AMS::startService(),返回值是启动的Service组件的名称。我们进入AMS分析:

    @Override
    public ComponentName AMS::startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        // Refuse possible leaked file descriptors
        if (service != null && service.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        if (callingPackage == null) {
            throw new IllegalArgumentException("callingPackage cannot be null");
        }

        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                "startService: " + service + " type=" + resolvedType);
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, callingPackage, userId);//调用startServiceLocked()
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }
mService是AMS内部,类型为ActiveService的实例对象;它是AMS启动一个服务的辅助类,封装了很多启动Service的业务函数。收下判断传参的合法性,随后调用ActiveService::startServiceLocked():

ComponentName ActiveService::startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
                + " type=" + resolvedType + " args=" + service.getExtras());

        final boolean callerFg;
        if (caller != null) {
            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
            if (callerApp == null) {
                throw new SecurityException(
                        "Unable to find app for caller " + caller
                        + " (pid=" + Binder.getCallingPid()
                        + ") when starting service " + service);
            }
            callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
        } else {
            callerFg = true;
        }

		//ServiceRecord是AMS中描述一个Service组件的类型
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false);//查找AMS中是否存在与参数service对应的ServiceRecord对象;如果不存在,则会通过PMS去获取与service对应的Service组件信息,并封装成ServiceLookupResult对象返回
        if (res == null) {
            return null;
        }
        if (res.record == null) {
            return new ComponentName("!", res.permission != null
                    ? res.permission : "private to package");
        }

        ServiceRecord r = res.record;

        ...
        r.lastActivity = SystemClock.uptimeMillis();
        r.startRequested = true;
        r.delayedStop = false;
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                service, neededGrants));

        final ServiceMap smap = getServiceMap(r.userId);

        ...

        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);//调用startServiceInnerLocked()去bring up一个Service
    }
一个服务的启动必须由一个应用组件去触发,所以启动Service的应用组件进程是不能不存在的。接着根据参数,检查AMS中是否已经这个服务的信息,即是否已经启动过它;如果AMS不存在当前需要启动的Service组件的信息,则去PMS查询,因为PMS会扫描所有Apk中的组件,根据参数从PMS查询,就会得到当前需要启动的Service对应的ServiceRecord对象,随后将它封装成ServiceLookupResult对象返回。


ServiceRecord是AMS用于管理Service的类型,每一个启动的Service,在AMS中都以ServiceRecord对象描述;就如ActivityRecord一样。


随后调用ActiveService::startServiceInnerLocked():

    ComponentName ActiveService::startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        ServiceState stracker = r.getTracker();
        if (stracker != null) {
            stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
        }
        r.callStart = false;
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startRunningLocked();
        }
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);//调用bringUpServiceLocked()去启动服务
        if (error != null) {
            return new ComponentName("!!", error);
        }

        if (r.startRequested && addToStarting) {
            boolean first = smap.mStartingBackground.size() == 0;
            smap.mStartingBackground.add(r);
            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
            if (DEBUG_DELAYED_SERVICE) {
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
            } else if (DEBUG_DELAYED_STARTS) {
                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
            }
            if (first) {
                smap.rescheduleDelayedStarts();
            }
        } else if (callerFg) {
            smap.ensureNotStartingBackground(r);
        }

        return r.name;
    }
主要处理就是调用bringUpServiceLocked()函数去启动当前的服务:
  private String ActiveService::bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        //Slog.i(TAG, "Bring up service:");
        //r.dump("  ");

        if (r.app != null && r.app.thread != null) {
            sendServiceArgsLocked(r, execInFg, false);//如果该Service已经启动,则直接传递Service参数到进程的主线程中,此时会触发调用onStartCommand();此次Service启动已经完成
            return null;
        }

        if (!whileRestarting && r.restartDelay > 0) {
            // If waiting for a restart, then do nothing.
            return null;
        }

        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);

        // We are now bringing the service up, so no longer in the
        // restarting state.
        if (mRestartingServices.remove(r)) {
            r.resetRestartCounter();
            clearRestartingIfNeededLocked(r);
        }

        // Make sure this service is no longer considered delayed, we are starting it now.
        if (r.delayed) {
            ...
        }

        // Make sure that the user who owns this service is started.  If not,
        // we don't want to allow it to run.
        if (!mAm.mUserController.hasStartedUserState(r.userId)) {
            String msg = "Unable to launch app "
                    + r.appInfo.packageName + "/"
                    + r.appInfo.uid + " for service "
                    + r.intent.getIntent() + ": user " + r.userId + " is stopped";
            Slog.w(TAG, msg);
            bringDownServiceLocked(r);
            return msg;
        }

        // Service is now being launched, its package can't be stopped.
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(
                    r.packageName, false, r.userId);
        } catch (RemoteException e) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying to unstop package "
                    + r.packageName + ": " + e);
        }

        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;//表示当前Service组件想要运行在其中的进程的名字
        ProcessRecord app;

        if (!isolated) {//isolated表示是否要求一个单独的进程来运行服务;TRUE为需要
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);//根据这个进程名字在AMS中查找该进程是否已经存在
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null && app.thread != null) {//如果进程已经启动,调用realStartServiceLocked()直接去启动Service
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);//该service想运行的进程已经存在,此时直接去启动该Service即可
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }

                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
        } else {
            // If this service runs in an isolated process, then each time
            // we call startProcessLocked() we will get a new isolated
            // process, starting another process if we are currently waiting
            // for a previous process to come up.  To deal with this, we store
            // in the service any current isolated process it is running in or
            // waiting to have come up.
            app = r.isolatedProc;//得到运行Service的单独的进程,第一次为null
        }

        // Not running -- get it started, and enqueue this service record
        // to be executed when the app comes up.
        if (app == null && !permissionsReviewRequired) {//如果该服务想要运行的进程还没有启动,则调用startProcessLocked()先去启动进程,再去启动Service
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                String msg = "Unable to launch app "
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                bringDownServiceLocked(r);
                return msg;//进程启动失败,退出
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }

        if (!mPendingServices.contains(r)) {//将当前需要启动Service的ServcieRecord对象加入到mPendingServices
            mPendingServices.add(r);
        }

        if (r.delayedStop) {
            // Oh and hey we've already been asked to stop!
            r.delayedStop = false;
            if (r.startRequested) {
                if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
                        "Applying delayed stop (in bring up): " + r);
                stopServiceLocked(r);
            }
        }

        return null;
    }
与Activity的启动类似,我们启动一个Service时,也需要判断当前Service是否已经启动过。结合Service的生命周期,如果该Service已经启动过,则直接去启动Service即可(即调用Service::onStartCommnad()函数),但Service::onCreate()不会被调用,因为onCreate()只在Service第一次创建时才会被调用;如果Service的宿主进程不存在,我们就先为该Service创建运行所需要的进程,然后再去启动它。为Service创建进程的流程与之前Activity启动时创建进程的过程基本一致,此处就不再分析。


我们假设此时我们是第一次启动该Service,此时需要为它创建进程。结合代码可知,在AMS发出了为Service创建进程的请求之后,会将当前的Service添加到mPendingServices集合中,它保存了所有需要去的Service的ServiceRecord对象。在进程创建完毕后,AMS就会遍历mPendingServices,去启动服务。


由Activity的启动过程分析可知,应用进程的入口函数是ActivityThread::main();应用进程启动完毕后,就会给AMS发送一个通知,告知AMS进程已经创建好了,可以去启动组件了。这个动作是在AMS::attachApplication(IApplicationThread)中处理的,参数是IApplicationThread类型;它用于AMS与当前应用进程的主线程交互。


集合之前分析Activity启动部分的内容,最终是在AMS::attachApplicationLocked(IApplicationThread, int)中处理:

    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        // Find the application record that is being attached...  either via
        // the pid if we are running in multiple processes, or just pull the
        // next app record if we are emulating process with anonymous threads.
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);//创建应用进程时,会将进程对象和pid保存到mPidsSelfLocked集合中,所以此时可以取出对应的进程对象
            }
        } else {
            app = null;
        }

        ...

        // If this application record is still attached to a previous
        // process, clean it up now.
        if (app.thread != null) {//如果app中已经有线程,说明app以前存在,现在是重启;先清理掉这些信息
            handleAppDiedLocked(app, true, true);
        }

        // Tell the process all about itself.

        if (DEBUG_ALL) Slog.v(
                TAG, "Binding process pid " + pid + " to record " + app);

        final String processName = app.processName;
        try {
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);//创建app死亡监听对象
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            startProcessLocked(app, "link fail", processName);
            return false;
        }

        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);

        app.makeActive(thread, mProcessStats);//会将创建的ActivityThread对应的ApplicationThread对象的Binder实例保存到该ProcessRecord对象的thread成员中,用以和该进程的主线程交互
        ...
        try {
            ...
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());//调用bindApplication()方法
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
            // todo: Yikes!  What should we do?  For now we will try to
            // start another process, but that could easily get us in
            // an infinite loop of restarting processes...
            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            startProcessLocked(app, "bind fail", processName);
            return false;
        }

        // Remove this record from the list of starting applications.
        mPersistentStartingProcesses.remove(app);
        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
                "Attach application locked removing on hold: " + app);
        mProcessesOnHold.remove(app);

        boolean badApp = false;
        boolean didSomething = false;

        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {//调用attachApplicationLocked(),去启动当前Activity组件堆栈最顶端的Activity
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        // Find any services that should be running in this process...
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);//检查mPendingServices中是否有Service组件需要在该新创建的进程中启动;在此之前,我们会把需要启动的Service组件添加到mPendingServices中
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }

        ...
        return true;
    }
与之前一样,先得到为当前Service启动而创建的新应用进程的ProcessRecord对象;调用ActivityThread::bindApplication()绑定应用信息,创建Instrumentation、LoadedApk和Application等对象。接着调用ActiveService::boolean attachApplicationLocked(ProcessRecord proc, String processName)启动服务:   

    boolean ActiveService::attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
        boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i 0) {
            ServiceRecord sr;
            for (int i=0; i
从mPendingServices中找到和当前进程匹配的ServiceRecord对象,即需要运行在当前新建进程的服务。调整mPendingServices集合,并调用ActiveService::realStartServiceLocked()去启动Service。除此之外,还会处理需要重启的Service。


分析ActiveService::realStartServiceLocked():

    private final void ActiveService::realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        if (app.thread == null) {
            throw new RemoteException();
        }
        if (DEBUG_MU)
            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
                    + ", ProcessRecord.uid = " + app.uid);
        r.app = app;//将Service运行的进程信息保存到对应的ServiceRecord对象中
        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

        final boolean newService = app.services.add(r);
        bumpServiceExecutingLocked(r, execInFg, "create");
        mAm.updateLruProcessLocked(app, false, null);
        mAm.updateOomAdjLocked();

        boolean created = false;
        try {
            if (LOG_SERVICE_START_STOP) {
                String nameTerm;
                int lastPeriod = r.shortName.lastIndexOf('.');
                nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
                EventLogTags.writeAmCreateService(
                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
            }
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startLaunchedLocked();
            }
            mAm.notifyPackageUse(r.serviceInfo.packageName,
                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);//调用scheduleCreateService在服务进程中创建Service对象,它会发送CREATE_SERVICE消息,最终在该进程的ActivityThread中处理会触发调用onCreate()
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            Slog.w(TAG, "Application dead when creating service " + r);
            mAm.appDiedLocked(app);
            throw e;
        } finally {
            if (!created) {
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);

                // Cleanup.
                if (newService) {
                    app.services.remove(r);
                    r.app = null;
                }

                // Retry.
                if (!inDestroying) {
                    scheduleServiceRestartLocked(r, false);
                }
            }
        }

        if (r.whitelistManager) {
            app.whitelistManager = true;
        }

        requestServiceBindingsLocked(r, execInFg);//处理bind service的情况:会将Service组件连接到请求绑定它的Activity中;内部会调用scheduleBindService()->handleBindService() -> onBind()被调用

        updateServiceClientActivitiesLocked(app, null, true);

        // If the service is in the started state, and there are no
        // pending arguments, then fake up one so its onStartCommand() will
        // be called.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null));
        }

        sendServiceArgsLocked(r, execInFg, true);//会触发调用Service::onStartCommand()

        ...
    }
首先,调用ActivityThread::scheduleCreateService()函数去创建当前启动的Service;中间的Binder调用关系就不再描述,之前已有过类似分析。直接看它的处理:
    private void ActivityThread::handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);//得到进程中加载的应用程序,以LoadedApk描述
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();//加载此时要启动的Service类,并创建其Servcie实例
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

			//为该Service设置Context上下文环境
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);//创建一个Application对象,用来描述该Service所属的应用程序;
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());//将一些信息与该Service组件进行绑定
            service.onCreate();//调用Service的onCreate()
            mServices.put(data.token, service);//token指向AMS中管理Service的ServiceRecord对象,保存到mService集合中
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);//通知AMS服务已经创建
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }
CreateServiceData封装了AMS传递的参数信息。首先,是去加载这个需要启动的Service。LoadedApk实例代表了一个被加载的应用信息,它与Application实例一样,都是在进程创建后的bindApplication()调用中被创建的;且进程内部,所有组件都共用这些对象。加载Service类之后,便会为Service设置当前Context信息;之后便将一些信息绑定到Service中,随后就会触发Service::onCreate()被调用,这时服务就已经创建完成,它的整个生命周期也就开始了。


再回到ActiveService::realStartServiceLocked()中,Service创建完毕后,start Service又会调用sendServiceArgsLocked()函数:

    private final void ActiveService::sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
        final int N = r.pendingStarts.size();
        if (N == 0) {
            return;
        }

        while (r.pendingStarts.size() > 0) {
            Exception caughtException = null;
            ServiceRecord.StartItem si = null;
            try {
                si = r.pendingStarts.remove(0);
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
                        + r + " " + r.intent + " args=" + si.intent);
                if (si.intent == null && N > 1) {
                    // If somehow we got a dummy null intent in the middle,
                    // then skip it.  DO NOT skip a null intent when it is
                    // the only one in the list -- this is to support the
                    // onStartCommand(null) case.
                    continue;
                }
                si.deliveredTime = SystemClock.uptimeMillis();
                r.deliveredStarts.add(si);
                si.deliveryCount++;
                if (si.neededGrants != null) {
                    mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
                            si.getUriPermissionsLocked());
                }
                bumpServiceExecutingLocked(r, execInFg, "start");
                if (!oomAdjusted) {
                    oomAdjusted = true;
                    mAm.updateOomAdjLocked(r.app);
                }
                int flags = 0;
                if (si.deliveryCount > 1) {
                    flags |= Service.START_FLAG_RETRY;
                }
                if (si.doneExecutingCount > 0) {
                    flags |= Service.START_FLAG_REDELIVERY;
                }
                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);//最终会调用Service::onStartCommand()
            } catch (TransactionTooLargeException e) {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large: intent="
                        + si.intent);
                caughtException = e;
            } catch (RemoteException e) {
                // Remote process gone...  we'll let the normal cleanup take care of this.
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
                caughtException = e;
            } catch (Exception e) {
                Slog.w(TAG, "Unexpected exception", e);
                caughtException = e;
            }

            if (caughtException != null) {
                // Keep nesting count correct
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                if (caughtException instanceof TransactionTooLargeException) {
                    throw (TransactionTooLargeException)caughtException;
                }
                break;
            }
        }
    }
如果这次Service start过程有参数(如参数intent中会封装一些指令)需要投递,则会触发ActivityThread::scheduleServiceArgs()将参数投递到Service中,触发一些后台执行流程:
    private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
                    res = s.onStartCommand(data.args, data.flags, data.startId);//此处会调用Service::onStartCommand()函数
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
                ensureJitEnabled();
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to start service " + s
                            + " with " + data.args + ": " + e.toString(), e);
                }
            }
        }
    }
ServiceArgsData封装了AMS传递的参数信息,我们的分析场景中不会牵扯到设置taskRemoved,所以这时就会触发调用Service::onStartCommand()调用,此时我们可以通过读取参数,来启动一些我们需要在该Service中执行的操作;至此,Service的有效生命周期就开始了。


回顾之前的分析,如果当时判断该Service已经启动过,即onCreate()已经调用过;则此时会直接调用sendServiceArgsLocked()函数,向Service中投递传入的参数,触发Service::onStartCommand()调用,而不会再去触发Service::onCreate()。这与我们所了解的Service的start生命周期是一致的。





你可能感兴趣的:(Android -- 系统start Service流程简要分析)