Service啓動過程源碼分析(Android Q)

Service的啓動概述

本章我們來分析Service的啓動過程。

Service生命週期

先來看下Service的生命週期:

startService和bindService啓動的服務生命週期略有不同。

Service啓動方式

我們啓動一個Serivce服務的時候,可以通過3種方式來啓動:

  • startService()方法,啓動一個Service。
  • bindService()方法,使用bind的方式啓動一個Service。
  • startForegroundService()方法,啓動一個前臺服務。

這幾種啓動方式,定義在Activity的父類型ContextWrapper類中,它們都通過調用mBase來執行具體實現,這裏的mBase,就是一個ContextImpl實例對象。

startService啓動——Client進程端

ContextImpl的相關實現

service啓動的幾個方法:

/frameworks/base/core/java/android/app/ContextImpl.java

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

    @Override
    public ComponentName startForegroundService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, true, mUser);
    }
    
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
    }
邏輯解析:
  1. startService和startForegroundService都調用了startServiceCommon方法,只是第二個參數不同(前臺服務是true)。
  2. bindService實現稍有不同,這裏調用了bindServiceCommon方法。

我們重點來分析startService的後續流程。

來看startServiceCommon方法:

    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
            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());
                } else if (cn.getPackageName().equals("?")) {
                    throw new IllegalStateException(
                            "Not allowed to start service " + service + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
邏輯解析:
  1. 驗證Intent相關設置,如果Service是隱式啓動,則在Android L之上會拋出錯誤,在小於該版本輸出提示日誌但不報錯。
  2. 判斷是否將要離開當前進程,並且設置Intent相關屬性。
  3. 調用AMS的startService方法來啓動Service,在此之後,代碼的執行由Client端切換到了系統服務AMS進程。

startService啓動——Server進程端

AMS的startService方法

AMS的startService方法:

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService"); //判斷是否是隔離的程序,如果是,則不允許執行,拋出錯誤
        ……
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res;
            try {
                res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, userId);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
            return res;
        }
    }
邏輯解析:
  1. 執行一些簡單的驗證工作,例如判斷是否是隔離程序,調用者的包名是否爲null等。
  2. 調用mServices.startServiceLocked執行啓動過程。這裏的mServices是ActiveServices的一個實例,用來管理Serivice的。

ActiveServices的startServiceLocked方法

ActiveServices的startServiceLocked方法:

/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage,
            final int userId, boolean allowBackgroundActivityStarts)
            throws TransactionTooLargeException {
        ……
        //判斷當前調用進程是否屬於前臺進程組(進程組優先級!= ProcessList.SCHED_GROUP_BACKGROUND)
        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=" + callingPid
                        + ") when starting service " + service);
            }
            callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
        } else {
            callerFg = true;
        }
        //調用retrieveServiceLocked方法來獲取一個ServiceLookupResult對象。
        ServiceLookupResult res =
            retrieveServiceLocked(service, null, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
        ……

        ServiceRecord r = res.record; //從ServiceLookupResult對象中,取出ServiceRecord對象,以進行後續操作。

        ……
        //處理、校驗啓動權限等相關的邏輯,並且判斷將要啓動的服務是否是前臺服務等。
        ……
        // At this point we've applied allowed-to-start policy based on whether this was
        // an ordinary startService() or a startForegroundService().  Now, only require that
        // the app follow through on the startForegroundService() -> startForeground()
        // contract if it actually targets O+.
        if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
            if (DEBUG_BACKGROUND_CHECK || DEBUG_FOREGROUND_SERVICE) {
                Slog.i(TAG, "startForegroundService() but host targets "
                        + r.appInfo.targetSdkVersion + " - not requiring startForeground()");
            }
            fgRequired = false; //fgRequired表示是否需要執行startForeground來啓動Service。
        }

        //對是否需要啓動前彈框進行判斷
        NeededUriGrants neededGrants = mAm.mUgmInternal.checkGrantUriPermissionFromIntent(
                callingUid, r.packageName, service, service.getFlags(), null, r.userId);

        ……

        ……
        if (fgRequired) { //啓動前臺服務
            // We are now effectively running a foreground service.
            ServiceState stracker = r.getTracker();
            if (stracker != null) {
                stracker.setForeground(true, mAm.mProcessStats.getMemFactorLocked(),
                        r.lastActivity);
            }
            mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
                    AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, true);
        }

        ……

        if (allowBackgroundActivityStarts) { //如果允許從後臺Activity啓動
            r.whitelistBgActivityStartsOnServiceStart();
        }
        //執行常規的啓動流程
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
    }
邏輯解析:
  1. 判斷當前調用者是否屬於前臺進程組(進程組優先級!= ProcessList.SCHED_GROUP_BACKGROUND)。
  2. 調用retrieveServiceLocked方法來獲取一個ServiceLookupResult對象。retrieveServiceLocked首先從緩存列表中查找是否已經存在該Service記錄,如果不存在,則從包資源裏解析獲取,最終生成一個含有Service信息的ServiceLookupResult對象。
  3. 從ServiceLookupResult對象中,取出ServiceRecord對象,以進行後續操作。
  4. 處理、校驗啓動權限等相關的邏輯,並且判斷將要啓動的服務是否是前臺服務等。
  5. fgRequired表示是否需要執行startForeground來啓動Service。
  6. 對是否需要啓動前彈框進行判斷。
  7. 如果是前臺服務,則執行啓動前臺服務。
  8. 調用startServiceInnerLocked執行常規的啓動流程。

ActiveServices的startServiceInnerLocked方法

    ComponentName 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);//更新ServiceRecord的ServiceState
        }
        r.callStart = false;
        StatsLog.write(StatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid, r.name.getPackageName(),
                r.name.getClassName(), StatsLog.SERVICE_STATE_CHANGED__STATE__START);
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startRunningLocked();//用於耗電統計,開啓運行的狀態
        }
        //service啓動的核心方法
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        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() + mAm.mConstants.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.rescheduleDelayedStartsLocked();//執行延遲啓動
            }
        } else if (callerFg || r.fgRequired) {
            smap.ensureNotStartingBackgroundLocked(r);//清楚map數據
        }

        return r.name;
    }
邏輯解析:
  1. 調用service的bringUpServiceLocked方法來啓動Service。
  2. 當啓動完成的時候設置啓動超時時間。
  3. 啓動成功之後將ServiceRecord加入到smap中的mStartingBackground中。
  4. 如果是第一次啓動則處理延遲啓動相關邏輯。

ActiveServices的bringUpServiceLocked方法

    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        if (r.app != null && r.app.thread != null) {//處理Service已經啓動的情況,此時只是發送新的StartItem
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }

        if (!whileRestarting && mRestartingServices.contains(r)) { //如果Service因爲crash被系統重啓,則return
            // If waiting for a restart, then do nothing.
            return null;
        }

        ……
        //正在啓動服務,因此不再處於重新啓動狀態,把service從重啓服務隊列中移除。
        if (mRestartingServices.remove(r)) {
            clearRestartingIfNeededLocked(r);
        }

        //確保此服務不再被視爲延遲,設置r.delayed爲false。
        if (r.delayed) {
            if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
            getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }

        // 確保擁有該服務的user已經啓動,如果未啓動,則終止操作,並執行清理工作。
        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;
        }

        // 服務正在啓動,設置package停止狀態爲false
        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);
        }
        //判斷當前服務是否需要在隔離進程中啓動。(如果在Manifest中設置了隔離進程的標誌位則該值等於標誌位的值)
        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
        ProcessRecord app;

        if (!isolated) { //常規進程中啓動
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg); //真正啓動Service的地方
                    return null;
                }
                ……
            }
        } else {
            ……
        }

        //處理進程沒有啓動的情況
        if (app == null && !permissionsReviewRequired) {
            //啓動service所要運行的進程
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingRecord, 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)) {//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;
    }
邏輯解析:
  1. 處理Service已經啓動的情況,此時只是發送新的StartItem,調用service.onStartCommand()過程。
  2. 如果Service因爲crash被系統重啓,則return。
  3. 正在啓動服務,因此不再處於重新啓動狀態,把service從重啓服務隊列中移除。
  4. 確保此服務不再被視爲延遲,設置r.delayed爲false。
  5. 確保擁有該服務的user已經啓動,如果未啓動,則終止操作,並執行清理工作。
  6. 服務正在啓動,設置package停止狀態爲false。
  7. 判斷當前服務是否需要在隔離進程中啓動。(如果在Manifest中設置了隔離進程的標誌位則該值等於標誌位的值)
  8. 如果不是在隔離進程中啓動,則調用realStartServiceLocked(r, app, execInFg); 真正啓動Service。
  9. 如果進程沒有啓動,啓動service所要運行的進程。
  10. mPendingServices保存待啓動服務,當進程啓動後,會重新啓動該服務。

ActiveServices的realStartServiceLocked方法

即將在Client中創建並啓動Service實例對象,從bindService()啓動的Service也會調用這個方法。

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ……
        這裏主要更新進程和ServiceRecord的一些信息
        
        bumpServiceExecutingLocked(r, execInFg, "create");//將service和進程關聯起來(更新ServiceRecord中的信息)
        //更新進程對應的優先級
        mAm.updateLruProcessLocked(app, false, null); 
        updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
        mAm.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);

        boolean created = false;
        try {
            ……
            mAm.notifyPackageUse(r.serviceInfo.packageName,
                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);//強制更改進程的狀態爲ActivityManager.PROCESS_STATE_SERVICE
            //調用Client端ApplicationThread對象的實例方法scheduleCreateService來創建Service。
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                    app.getReportedProcState());
            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.setProcess(null);
                }

                // Retry.
                if (!inDestroying) {
                    scheduleServiceRestartLocked(r, false);//嘗試重新啓動服務
                }
            }
        }

        if (r.whitelistManager) {
            app.whitelistManager = true;
        }
        //如果調用過bindService,則會調用requestServiceBindingsLocked()執行onBind方法。
        requestServiceBindingsLocked(r, execInFg);
        //如果客戶端Bind Service成功,按需更新服務端進程優先級
        updateServiceClientActivitiesLocked(app, null, true);

        if (newService && created) {
            app.addBoundClientUidsOfNewService(r);
        }

        //如果service已經啓動,並且符合條件,則方法onStartCommand() 將被調用
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null, 0));
        }

        sendServiceArgsLocked(r, execInFg, true); 

        if (r.delayed) {//如果service是延時啓動的則將其從mDelayedStartList中移除
            if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
            getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }

        if (r.delayedStop) { //如果service被主動要求停止那麼調用
            // 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 (from start): " + r);
                stopServiceLocked(r);
            }
        }
    }
邏輯解析:
  1. 更新進程和ServiceRecord的一些信息,並將service和進程關聯起來(更新ServiceRecord中的信息)。
  2. 更新進程對應的優先級。
  3. 強制更改進程的狀態爲ActivityManager.PROCESS_STATE_SERVICE。
  4. 調用Client端ApplicationThread對象的實例方法scheduleCreateService來創建Service。
  5. 如果服務創建失敗,則執行清理工作,並且嘗試重新啓動服務。
  6. 如果調用過bindService,則會調用requestServiceBindingsLocked()執行onBind方法,成功後,更新進程優先級。
  7. 如果service已經啓動,並且符合條件,則方法onStartCommand() 將被調用。
  8. 如果service是延時啓動的則將其從mDelayedStartList中移除。
  9. 如果service被主動要求停止那麼調用。

startService啓動——回到Client端

在ActiveServices的realStartServiceLocked方法中,調用了Client端ApplicationThread對象的實例方法scheduleCreateService來創建Service。

ApplicationThread對象的scheduleCreateService方法:

android.app.ActivityThread.java

        public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }

這裏發生給Handler一個CREATE_SERVICE的消息,我們直接來看該消息的處理方法。

    private void handleCreateService(CreateServiceData data) {
        //對將要進行GC進行處理。
        unscheduleGcIdler();
        //獲得這個進程對應的LoadedApk對象
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            //通過反射調用,創建一個Serice對象
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
        } catch (Exception e) {
            ……
        }

        try {
            ……
            //創建Service的ContextImpl對象
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
            //獲取進程對應的Application對象。
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            //調用service對象的attach方法進行初始化設置
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            //調用Service的onCreate方法。
            service.onCreate();
            mServices.put(data.token, service);//添加服務到mServices中
            try {
                //通知AMS service啓動成功,進行取消超時消息等操作
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } 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);
            }
        }
    }
邏輯解析:
  1. 對將要進行GC進行處理,跳過。
  2. 獲得這個進程對應的LoadedApk對象。
  3. 通過反射調用,創建一個Serice對象。
  4. 創建Service的ContextImpl對象。
  5. 獲取進程對應的Application對象。
  6. 調用service對象的attach方法進行初始化設置。
  7. 調用Service的onCreate方法。
  8. 添加服務到mServices中。
  9. 通知AMS service啓動成功,進行取消超時消息等操作。

到了這裏,Service已經完成了啓動過程。

Service的onStartCommand調用過程

那麼Service的onStartCommand又是怎麼樣的調用流程呢?

它的起點是ActiveServices的sendServiceArgsLocked方法:

    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
        ……
        try {
            r.app.thread.scheduleServiceArgs(r, slice);
        }
        ……
    }

這裏調用了ApplicationThread對象的scheduleServiceArgs方法,該方法又給ActivityThread對象的Handler對象發送了H.SERVICE_ARGS消息,最終調用handleServiceArgs方法來處理該消息。

    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);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }
                ……
        }
    }

這裏調用了Servcie對象的onStartCommand方法。

到了這裏,Service的啓動邏輯相關的重要過程也就分析完了。

總結

通過本文分析,我們對startSerivce的啓動流程已經瞭解了,這裏來做一個簡單的總結:

  1. 可以通過3種方式來啓動一個Serivce服務:startService()方法,啓動一個Service;bindService()方法,使用bind的方式啓動一個Service;startForegroundService()方法,啓動一個前臺服務。
  2. 上述3種啓動方法的是在ContextImpl中實現的。
  3. startService啓動在Client進程端發起,並且進行Intent相關設置,以及一些校驗工作。
  4. 然後進入到Server端(AMS所在進程),AMS使用ActiveServices類來對服務進行管理,系統服務端的主要處理工作都是在ActiveServices中進行的,最終調用到ActiveServices的realStartServiceLocked方法。
  5. ActiveServices的realStartServiceLocked方法調用了Client端ApplicationThread對象的實例方法scheduleCreateService來創建Service(回到Client端來進行Service的創建,這裏的Client是Service的所在進程,不一定是啓動時發起請求的Client進程了,這裏需要注意)。
  6. ActiveServices的sendServiceArgsLocked方法最終調用了Service的onStartCommand方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章