Service-启动过程

Post on Nov 08, 2022 by Wei Lin

概述

bindService()启动过程

(1) 发起端进程

Context.bindService() ->
ContextWrapper.bindService() ->
ContextImpl.bindService() ->
ContextImpl.bindServiceCommon()

之后调用bindIsolatedService()方法与AMS交互。


(1) AMS与服务端处理部分

AMS.bindIsolatedService() ->
ActiveServices.bindServiceLocked()

之后分为3种情况:


  • 如果Service已启动,则只回调onBind()
AS.requestServiceBindingLocked() ->
ActivityThread.ApplicationThread.scheduleBindService(){sendMessage(H.BIND_SERVICE, s)} ->
ActivityThread.handleBindService() ->
MyService.onBind()


  • 如果进程已存在但Service未启动,需要回调onCreate()和onBind()
AS.retrieveServiceLocked() ->
AS.bringUpServiceLocked() ->
AS.realStartServiceLocked() ->
AT.scheduleCreateService(){ sendMessage(H.CREATE_SERVICE, s); } ->
AT.handleCreateService()->
MyService.onCreate()

执行完onCreate(),函数返回到AS.realStartServiceLocked()中,继续执行:

AS.requestServiceBindingsLocked() ->
ActivityThread.ApplicationThread.scheduleBindService(){sendMessage(H.BIND_SERVICE, s)} ->
ActivityThread.handleBindService() ->
MyService.onBind()

在AT.handleBindService()中还会执行publishService(),其作用是创建客户端到服务端的连接。

try {
    if (!data.rebind) {
        IBinder binder = s.onBind(data.intent);
        ActivityManager.getService().publishService(
                data.token, data.intent, binder);
    } else {
        s.onRebind(data.intent);
        ActivityManager.getService().serviceDoneExecuting(
                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
    }
} catch (RemoteException ex) {
    throw ex.rethrowFromSystemServer();
}


  • 如果进程不存在
ServiceRecord.retrieveAppBindingLocked() ->
ActiveServices.bringUpServiceLocked() ->
AMS.startProcessLocked()  //将ServiceRecord对象添加到mPendingServices中
//...
//启动进程流程,之后进入APP的main()
ActivityThread.main() ->
ActivityThread.attach() ->
AMS.attachApplication() ->
AS.attachApplicationLocked() -> //处理之前的mPendingServices
AS.realStartServiceLocked()

之后的逻辑就和“进程已存在但Service未启动”中的AS.realStartServiceLocked()后的处理流程一样了。

startForegroundService()启动过程

(1) Service生命周期

开启前台Service:

serviceIntent = new Intent(this, MyService.class);
startForegroundService(serviceIntent);

APP端:

ContextWrapper.startForegroundService() ->
ContextImpl.startForegroundService() ->
ContextImpl.startServiceCommon(intent,requireForeground=true,user)


System端:

在AS.bringUpServiceLocked()中,如果进程存在,则继续向下;如果不存在,则启动进程然后继续向下执行realStartServiceLocked()。在该函数中会调用sendServiceArgsLocked()发送前台通知延时消息。

AMS.startService() ->
AS.startServiceLocked(9 args) ->
AS.startServiceLocked(10 args) ->
AS.startServiceInnerLocked() ->
AS.bringUpServiceLocked() ->
判断进程是否启动 ->
AS.realStartServiceLocked()

在realStartServiceLocked()执行以下流程并回调到APP端:

AT.handleCreateService() // 执行onCreate

AS.sendServiceArgsLocked() // 执行onStartCommand

前台通知启动过程

在自定义MyService的onStartCommand()中还需要执行startForeground(int id, notification),其流程如下:

startForeground(int id, notification)
Service.startForeground(int id, notification)
AMS.setServiceForeground()
AS.setServiceForegroundLocked()
AS.setServiceForegroundInnerLocked()
ServiceRecord.postNotification()
NMS.enqueueNotification()
NMS.enqueueNotificationInternal(8 args)
NMS.enqueueNotificationInternal(9 args)

实际上在AS.realStartServiceLocked()中也会调用ServiceRecord.postNotification(),但如果是首次启动Service,则会因为isForeground=false及foregroundNoti = null而退出。

public void postNotification() {
    if (isForeground && foregroundNoti != null && app != null) {
        //...
    }
}

Android 12+通知延迟10s显示

Android 12+系统会等待10s才显示跟前台Service有关的通知(为短期运行的FGS提供优化体验),以下情况可以豁免(即立刻显示通知):

  • The service is associated with a notification that includes action buttons.
  • The service has a foregroundServiceType of mediaPlayback, mediaProjection, or phoneCall.
  • The service provides a use case related to phone calls, navigation, or media playback, as defined in the notification’s category attribute.
  • Service在配置通知时调用setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)


在Notification.shouldShowForegroundImmediately()中判断是否立刻显示通知,调用流程如下:

NMS.enqueueNotification()
NMS.enqueueNotificationInternal(8 args)
NMS.enqueueNotificationInternal(9 args)
AMS.applyForegroundServiceNotification()
AS.applyForegroundServiceNotificationLocked()
AS.shouldShowFgsNotificationLocked()

startService()启动过程

Base on: Android 11

1.应用端启动Service

(1) 自定义的Service

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d("MyService", "onBind executed");
    }
    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}


(2) 启动Service

public class MainActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent startIntent = new Intent(this, MyService.class);
        startService(startIntent); 	// 启动服务
    }
}


(3) 调用ContextWrapper.startService()

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {......}

public class ContextThemeWrapper extends ContextWrapper {......}

2.ContextWrapper.startService()

在ContextWrapper.startService()中调用mBase.startService(Intent service),此处的mBase 实际上是一个ContextImpl对象,ContextWrapper在此处用了装饰者模式。

public class ContextWrapper extends Context {

    Context mBase;
    public ContextWrapper(Context base) {
        mBase = base;
    }

    @Override
    public ComponentName startService(Intent service) {
        return mBase.startService(service);
    }
}

3.ContextImpl.startService()

class ContextImpl extends Context {
public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, false, mUser);
    }

/**
 * Logs a warning if the system process directly called a method such as
 * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
 * The "AsUser" variants allow us to properly enforce the user's restrictions.
 */
    private void warnIfCallingFromSystemProcess() {
        if (Process.myUid() == Process.SYSTEM_UID) {
            Slog.w(TAG, "Calling a method in the system process without a qualified user: "
                    + Debug.getCallers(5));
        }
    }

}

如果进程system_server直接调用ContextImpl.startService()而不是startServiceAsUser(),则会打印警告信息和前5行堆栈。

4.ContextImpl.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(), getAttributionTag(), 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();
    }
}

validateServiceIntent(service)用于检验service,若service为空则throw异常。

然后通过ActivityManager.getService()进行Binder调用,获取服务端AMS的引用。

ActivityManager.java中的Binder调用过程如下:

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

5.AMS.startService()

public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, boolean requireForeground, String callingPackage,
        String callingFeatureId, 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 + " fg=" + requireForeground);
    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, callingFeatureId, userId);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return res;
       }
}

方法参数说明:

caller:IApplicationThread类型,复杂处理

service:Intent类型,包含需要运行的service信息

resolvedType:String类型

callingPackage: String类型,调用该方法的package

userId: int类型,用户的id

6.AS.startServiceLocked(9 args)

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, boolean fgRequired, String callingPackage,
        @Nullable String callingFeatureId, final int userId)
        throws TransactionTooLargeException {
    return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
            callingPackage, callingFeatureId, userId, false);
}

7.AS.startServiceLocked(11 args)

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, boolean fgRequired,
        String callingPackage, @Nullable String callingFeatureId, final int userId,
        boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
        throws TransactionTooLargeException {...}

8.AS.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);
    }
    r.callStart = false;
    FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid,
            r.name.getPackageName(), r.name.getClassName(),
            FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START);
    synchronized (r.stats.getBatteryStats()) {
        r.stats.startRunningLocked();
    }
    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);
    }

    return r.name;
}

9.AS.bringUpServiceLocked()

代码较多

这里分为两种情况:

进程已存在->AS.realStartServiceLocked()

if (app != null && app.thread != null) {
    try {
        app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
        realStartServiceLocked(r, app, execInFg);
        return null;
    } catch (TransactionTooLargeException e) {
        throw e;
    } catch (RemoteException e) {
        Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
    }

    // If a dead object exception was thrown -- fall through to
    // restart the application.
}

进程不存在->AMS.startProcessLocked()

当目标进程不存在,则先执行startProcessLocked创建进程,经过层层调用最后会调用到AMS.attachApplicationLocked, 然后再执行realStartServiceLocked()。

if (app == null && !permissionsReviewRequired) {
    // TODO (chriswailes): Change the Zygote policy flags based on if the launch-for-service
    //  was initiated from a notification tap or not.
    if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
            hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, 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;
    }
}

(1) AMS端

ActiveServices.bringUpServiceLocked() ->
ActivityManagerService.startProcessLocked() ->
ProcessList.startProcessLocked() ->
ProcessList.startProcessLocked() ->
ProcessList.startProcessLocked() ->
ProcessList.startProcessLocked()


(2) Zygote流程

在Zygote进程中创建新进程,然后调用到ActivityThread.main()。


(3) 新进程

ActivityThread.main() ->
ActivityThread.attach() ->
AMS.attachApplication()


(4) AMS端

IActivityManager$Stub.onTransact() ->
ActivityManagerService.attachApplication() ->
ActivityManagerService.attachApplicationLocked() ->
ActiveServices.attachApplicationLocked() ->
ActiveServices.realStartServiceLocked()

10.AS.realStartServiceLocked()

private final void 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.setProcess(app);
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

    final boolean newService = app.startService(r);
    bumpServiceExecutingLocked(r, execInFg, "create");
//......

    boolean created = false;
    try {
        if (LOG_SERVICE_START_STOP) {
            String nameTerm;
            int lastPeriod = r.shortInstanceName.lastIndexOf('.');
            nameTerm = lastPeriod >= 0 ? r.shortInstanceName.substring(lastPeriod)
                    : r.shortInstanceName;
            EventLogTags.writeAmCreateService(
                    r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
        }
        FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_LAUNCH_REPORTED, r.appInfo.uid,
                r.name.getPackageName(), r.name.getClassName());
        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.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                app.getReportedProcState());
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
//......
    } finally {
        if (!created) {
            // Keep the executeNesting count accurate.
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
            // ......
            }
            // ......
        }
    }

//......
    sendServiceArgsLocked(r, execInFg, true);
//......
}

(1) 通过bumpServiceExecutingLocked发送延迟消息

AS.bumpServiceExecutingLocked()->AS.scheduleServiceTimeoutLocked()


(2) 通过scheduleCreateService()进入onCreate

通过app.thread.scheduleCreateService()执行APP端的调用,其中app.thread是一个IApplicationThread对象,其服务端的实现位于ActivityThread.java:

private class ApplicationThread extends IApplicationThread.Stub {......}


(3) 通过serviceDoneExecutingLocked移除延迟消息


(4) 通过sendServiceArgsLocked()进入onStartCommand

AS.bumpServiceExecutingLocked()-发送延时消息

private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
    //......
    if (r.executeNesting == 0) {
        //......
        if (r.app != null) {
            r.app.executingServices.add(r);
            r.app.execServicesFg |= fg;
            if (timeoutNeeded && r.app.executingServices.size() == 1) {
                scheduleServiceTimeoutLocked(r.app);
            }
        }
    } else if (r.app != null && fg && !r.app.execServicesFg) {
        r.app.execServicesFg = true;
        if (timeoutNeeded) {
            scheduleServiceTimeoutLocked(r.app);
        }
    }
//......
}

bumpServiceExecutingLocked()调用AS.scheduleServiceTimeoutLocked(r.app),该函数会发送一个延迟处理的消息SERVICE_TIMEOUT_MSG。在方法AT.scheduleCreateService()执行完成,也就是onCreate回调执行完成之后,便会remove掉该消息。但是如果没能在延时时间之内remove该消息,则会进入执行service timeout流程。

void scheduleServiceTimeoutLocked(ProcessRecord proc) {
    if (proc.executingServices.size() == 0 || proc.thread == null) {
        return;
    }
    Message msg = mAm.mHandler.obtainMessage(
            ActivityManagerService.SERVICE_TIMEOUT_MSG);
    msg.obj = proc;
    mAm.mHandler.sendMessageDelayed(msg,
            proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}

AT.scheduleCreateService()->onCreate()

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);
}

然后执行线程间的消息传递:

class H extends Handler {
    //......
    @UnsupportedAppUsage
    public static final int RECEIVER                = 113;
    @UnsupportedAppUsage
    public static final int CREATE_SERVICE          = 114;
    @UnsupportedAppUsage
    public static final int SERVICE_ARGS            = 115;
    //.......

    String codeToString(int code) {
        if (DEBUG_MESSAGES) {
            switch (code) {
                case BIND_APPLICATION: return "BIND_APPLICATION";
                case EXIT_APPLICATION: return "EXIT_APPLICATION";
                case RECEIVER: return "RECEIVER";
                case CREATE_SERVICE: return "CREATE_SERVICE";
                case SERVICE_ARGS: return "SERVICE_ARGS";
                case STOP_SERVICE: return "STOP_SERVICE";
                //......
            }
        }
        return Integer.toString(code);
    }
    public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            //......
            case CREATE_SERVICE:
                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                            ("serviceCreate: " + String.valueOf(msg.obj)));
                }
                handleCreateService((CreateServiceData)msg.obj);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
            //......
        }

AS.serviceDoneExecutingLocked(3 arg)->移除延时消息

boolean created表示是否成功创建Service。

初始时,created = false,在执行try{……}中的代码时,若发生异常,则表示service创建失败(即不会执行created = true),于是在catch中报出DeadObjectException错误并打印相关日志后,然后在finally代码块中执行serviceDoneExecutingLocked()用于移除之前AS.bumpServiceExecutingLocked()发送的延时消息。

boolean created = false;
try {
//......
    app.thread.scheduleCreateService(r, r.serviceInfo,
            mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
            app.getReportedProcState());
    r.postNotification();
    created = true;
} catch (DeadObjectException e) {
//......
} finally {
    if (!created) {
        // Keep the executeNesting count accurate.
        final boolean inDestroying = mDestroyingServices.contains(r);
        serviceDoneExecutingLocked(r, inDestroying, inDestroying);

        // Cleanup.
        if (newService) {
            app.stopService(r);
            r.setProcess(null);
        }

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

注:在AT.scheduleCreateService()->onCreate()的调用栈中,也会执行一次scheduleServiceRestartLocked(),此时是service创建成功时的情况。

AS.sendServiceArgsLocked()->onStartCommand()

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
        boolean oomAdjusted) throws TransactionTooLargeException {
        //......
        bumpServiceExecutingLocked(r, execInFg, "start");
        if (!oomAdjusted) {
            oomAdjusted = true;
            mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
        }
        //......

    ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
    slice.setInlineCountLimit(4);
    Exception caughtException = null;
    try {
        r.app.thread.scheduleServiceArgs(r, slice);
    } catch (TransactionTooLargeException e) {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large for " + args.size()
                + " args, first: " + args.get(0).args);
        Slog.w(TAG, "Failed delivering service starts", e);
        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);
        Slog.w(TAG, "Failed delivering service starts", e);
        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);
        for (int i = 0; i < args.size(); i++) {
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
        }
        if (caughtException instanceof TransactionTooLargeException) {
            throw (TransactionTooLargeException)caughtException;
        }
    }
}

此函数中的执行代码类似于AS.realStartServiceLocked()。

(1) 通过bumpServiceExecutingLocked发送延迟消息

AS.bumpServiceExecutingLocked()->AS.scheduleServiceTimeoutLocked()


(2) 通过scheduleServiceArgs()进入onStartCommand

通过app.thread.scheduleServiceArgs()执行APP端的调用,其中app.thread是一个IApplicationThread对象,其服务端的实现位于ActivityThread.java:

private class ApplicationThread extends IApplicationThread.Stub {
    //......
    public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
        List<ServiceStartArgs> list = args.getList();

        for (int i = 0; i < list.size(); i++) {
            ServiceStartArgs ssa = list.get(i);
            ServiceArgsData s = new ServiceArgsData();
            s.token = token;
            s.taskRemoved = ssa.taskRemoved;
            s.startId = ssa.startId;
            s.flags = ssa.flags;
            s.args = ssa.args;

            sendMessage(H.SERVICE_ARGS, s);
        }
        //......
    }


}

向ActivityThread发送SERVICE_ARGS消息,然后执行AT.handleServiceArgs():


(3) 通过serviceDoneExecutingLocked移除延迟消息

if (caughtException != null) {
    // Keep nesting count correct
    final boolean inDestroying = mDestroyingServices.contains(r);
    for (int i = 0; i < args.size(); i++) {
        serviceDoneExecutingLocked(r, inDestroying, inDestroying);
    }
    if (caughtException instanceof TransactionTooLargeException) {
        throw (TransactionTooLargeException)caughtException;
    }
}

若发生异常,则抛出异常并移除超时消息。

<执行AT.scheduleCreateService()分支>

11.AT.handleCreateService()

private void 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);
    Service service = null;
    try {
        if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = packageInfo.getAppFactory()
                .instantiateService(cl, data.info.name, data.intent);
        // Service resources must be initialized with the same loaders as the application
        // context.
        context.getResources().addLoaders(
                app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

        context.setOuterContext(service);
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManager.getService());
        service.onCreate();
        mServices.put(data.token, service);
        try {
            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);
        }
    }
}

Service.onCreate()

到此进入了APP端的Service生命周期,并最终调用service.onCreate()方法,此处的service是继承于Service类的自定义service,通过service = packageInfo.getAppFactory().instantiateService()赋值。

自定义服务都是继承于Service,并覆写该方式,调用service.onCreate()方法,最终调用到Service.onCreate()。

AMS.serviceDoneExecuting()

由AT.handleCreateService()中的:

try {
    ActivityManager.getService().serviceDoneExecuting(
        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
    throw e.rethrowFromSystemServer();
}

调用而来。

AMS.serviceDoneExecuting()的具体代码:

final ActiveServices mServices;

public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
    synchronized(this) {
        if (!(token instanceof ServiceRecord)) {
            Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
            throw new IllegalArgumentException("Invalid service token");
        }
        mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
    }
}

然后调用4参数的AS.serviceDoneExecutingLocked()
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
    boolean inDestroying = mDestroyingServices.contains(r);
    if (r != null) {
        //......
        final long origId = Binder.clearCallingIdentity();
        serviceDoneExecutingLocked(r, inDestroying, inDestroying);
        Binder.restoreCallingIdentity(origId);
    } else {
        Slog.w(TAG, "Done executing unknown service from pid "
                + Binder.getCallingPid());
    }
}


然后调用3参数的AS.serviceDoneExecutingLocked():

private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
        boolean finishing) {
    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING " + r
            + ": nesting=" + r.executeNesting
            + ", inDestroying=" + inDestroying + ", app=" + r.app);
    else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
            "<<< DONE EXECUTING " + r.shortInstanceName);
    r.executeNesting--;
    if (r.executeNesting <= 0) {
        if (r.app != null) {
            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                    "Nesting at 0 of " + r.shortInstanceName);
            r.app.execServicesFg = false;
            r.app.executingServices.remove(r);
            if (r.app.executingServices.size() == 0) {
                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
                        "No more executingServices of " + r.shortInstanceName);
                mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
            } else if (r.executeFg) {
                // Need to re-evaluate whether the app still needs to be in the foreground.
                for (int i=r.app.executingServices.size()-1; i>=0; i--) {
                    if (r.app.executingServices.valueAt(i).executeFg) {
                        r.app.execServicesFg = true;
                        break;
                    }
                }
            }
            if (inDestroying) {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                        "doneExecuting remove destroying " + r);
                mDestroyingServices.remove(r);
                r.bindings.clear();
            }
            mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
        }
        r.executeFg = false;
        if (r.tracker != null) {
            final int memFactor = mAm.mProcessStats.getMemFactorLocked();
            final long now = SystemClock.uptimeMillis();
            r.tracker.setExecuting(false, memFactor, now);
            r.tracker.setForeground(false, memFactor, now);
            if (finishing) {
                r.tracker.clearCurrentOwner(r, false);
                r.tracker = null;
            }
        }
        if (finishing) {
            if (r.app != null && !r.app.isPersistent()) {
                r.app.stopService(r);
                r.app.updateBoundClientUids();
                if (r.whitelistManager) {
                    updateWhitelistManagerLocked(r.app);
                }
            }
            r.setProcess(null);
        }
    }
}

若service的create一切正常,无超时发生,则在此步通过 mAm.mHandler.removeMessages()移除service启动超时消息SERVICE_TIMEOUT_MSG。通常超时原因是因为service的onCreate()方法执行时间过长。

<AT.scheduleCreateService()分支完成>

<执行AS.sendServiceArgsLocked()分支>

12.AT.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;
            }

            QueuedWork.waitToFinish();

            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to start service " + s
                        + " with " + data.args + ": " + e.toString(), e);
            }
        }
    }
}

同onCreate一样,此处执行service在APP端的生命周期。

Service.onStartCommand()

public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) {
    onStart(intent, startId);
    return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}

public void onStart(Intent intent, int startId) {
}

onStartCommand()调用onStart()。

AMS.serviceDoneExecuting()

调用栈同AT.handleCreateService()中一样。

若service的onStartCommand的执行一切正常,无超时发生,则在此步通过 mAm.mHandler.removeMessages()移除service启动超时消息SERVICE_TIMEOUT_MSG。通常超时原因是因为service的onStartCommand()方法执行时间过长。

<AS.sendServiceArgsLocked()分支完成>