likes
comments
collection
share

【源码解析】Service的启动过程

作者站长头像
站长
· 阅读数 3

一、前言

我们知道Service一般有两种工作状态,一种是启动状态,一种是绑定状态启动状态的Service是这样生成的:

Intent intent = new Intent(this, MyService.class);
startService(intent);

绑定状态的Service是这样生成的:

Intent intent = new Intent(this, MyService.class);
bindService(intent, mServiceConnection, BIND_ATUO_CREATE);

针对这两种Service,我们从源码的角度分析一下两种工作状态的区别。

以下源码分析是基于Android SDK 27

二、启动状态的Service

从启动状态的Service的生成代码中可以知道,入口是ContextImpl的startService方法,如下所示。

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

startService方法调用了startServiceCommon方法,如下所示。

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
        UserHandle user) {
    try {
        validateServiceIntent(service);
        service.prepareToLeaveProcess(this);
        //调用了AMS的startService方法
        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();
    }
}

startServiceCommon方法又通过ActivityManager.getService()对象调用了startService方法。而ActivityManager.getService()对象就是ActivityManagerService服务(AMS)。我们转到ActivityManagerService的startService方法,如下所示。

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

在上面的代码中,AMS通过了mServices这个对象,调用了mServices的startServiceLocked方法,而mServices是ActiveServices类型,它的startServiceLocked方法如下所示。

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
        throws TransactionTooLargeException {
    final boolean callerFg;
    if (caller != null) {
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        if (callerApp == null) {
            throw new SecurityException();
        }
        callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
    } else {
        callerFg = true;
    }

    ...省略

    ServiceRecord r = res.record;

    if (!r.startRequested && !fgRequired) {
        final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
                r.appInfo.targetSdkVersion, callingPid, false, false);
        ...省略
    }

    NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
            callingUid, r.packageName, service, service.getFlags(), null, r.userId);

    if (mAm.mPermissionReviewRequired) {
        if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,
                callingUid, service, callerFg, userId)) {
            return null;
        }
    }

    if (unscheduleServiceRestartLocked(r, callingUid, false)) {
        ...省略
    }
    ...省略
    if (!callerFg && !fgRequired && r.app == null
            && mAm.mUserController.hasStartedUserState(r.userId)) {
        ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
        if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
            ...省略
            addToStarting = true;
        } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
            addToStarting = true;
        } else if (DEBUG_DELAYED_STARTS) {
            ...省略
        }
    } else if (DEBUG_DELAYED_STARTS) {
        ...省略
    }

    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    return cmp;
}

为了能关注重点代码,我们将部分代码逻辑省略掉了。最终ActiveServices的startServiceLocked方法调用了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;
    synchronized (r.stats.getBatteryStats()) {
        r.stats.startRunningLocked();
    }
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
    if (error != null) {
        return new ComponentName("!!", error);
    }

    ...省略

    return r.name;
}

startServiceInnerLocked方法继续调用了ActiveServices的内部方法——bringUpServiceLocked,而bringUpServiceLocked方法又继续调用了realStartServiceLocked方法。如下所示。

private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
    ...省略

    boolean created = false;
    try {
        ...省略
        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);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        Slog.w(TAG, "Application dead when creating service " + r);
        mAm.appDiedLocked(app);
        throw e;
    } finally {
        ...省略
    }

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

    requestServiceBindingsLocked(r, execInFg);

    updateServiceClientActivitiesLocked(app, null, true);

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

    ...省略
}

在上面的方法中,通过调用app.thread对象的scheduleCreateService方法来创建Service。而app.thread对象是ActivityThread类型的。所以,创建Service就转化到了ActivityThread的scheduleCreateService方法,如下所示。

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

scheduleCreateService方法中,通过sendMessage方法,发送了一个通知,其处理者是ActivityThread的内部类H,H继承了Handler,其中的handleMessage方法处理了上面的通知。在handleMessage方法中,对于H.CREATE_SERVICE的处理,如下所示。

case CREATE_SERVICE:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
    handleCreateService((CreateServiceData)msg.obj);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;

上面的逻辑中,调用了handleCreateService方法,如下所示。

private void handleCreateService(CreateServiceData data) {
    unscheduleGcIdler();

    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
    	//1、使用反射的形式创建了Service对象
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
        
    }

    try {
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
        //2、如果Application对象没有创建,则创建一个Application对象。在其中调用了Application的生命周期方法
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        //3、调用Service对象的attach方法
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManager.getService());
        //4、调用Service对象的onCreate方法
        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);
        }
    }
}

上面的代码中,主要执行了以下几个步骤。 1、使用了反射的形式创建了Service对象。 2、如果Application对象没有创建,则创建Application对象,并调用其中的生命周期函数。 3、调用Service对象的attach生命周期方法。 4、调用Service对象的onCreate生命周期方法。

至此,启动状态的Service已经创建并运行起来了。而它的销毁过程其实和创建过程的流程差不多,最终都是在ActivityThread中执行相关的逻辑。这里就不再详细分析。我们接下来说一下绑定状态下的Service的工作过程。

三、绑定状态的Service

从绑定状态的Service的生成代码中可以知道,入口是ContextImpl的bindService方法,如下所示。

public boolean bindService(Intent service, ServiceConnection conn,
        int flags) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
            Process.myUserHandle());
}

ContextImpl中的bindService方法调用了bindServiceCommon方法,如下所示。

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
        handler, UserHandle user) {
    // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
    IServiceConnection sd;
    if (conn == null) {
        throw new IllegalArgumentException("connection is null");
    }
    if (mPackageInfo != null) {
    	//1、传入ServiceConnection对象获取一个IServiceConnection对象
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    } else {
        throw new RuntimeException("Not supported in system context");
    }
    validateServiceIntent(service);
    try {
        IBinder token = getActivityToken();
        if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
                && mPackageInfo.getApplicationInfo().targetSdkVersion
                < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            flags |= BIND_WAIVE_PRIORITY;
        }
        service.prepareToLeaveProcess(this);
        //2、调用了AMS的bindService方法
        int res = ActivityManager.getService().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());
        if (res < 0) {
            throw new SecurityException(
                    "Not allowed to bind to service " + service);
        }
        return res != 0;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

上面的代码中,调用了ActivityManager.getService()对象的bindService方法。前面我们分析启动状态的Service时,就知道了ActivityManager.getService()对象是一个ActivityManagerService(AMS)对象,所以我们转到了ActivityManagerService的bindService方法,如下所示。

public int bindService(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, IServiceConnection connection, int flags, String callingPackage,
        int userId) throws TransactionTooLargeException {
    enforceNotIsolatedCaller("bindService");

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

    synchronized(this) {
        return mServices.bindServiceLocked(caller, token, service,
                resolvedType, connection, flags, callingPackage, userId);
    }
}

ActivityManagerService的bindService方法中,使用了mServices的bindServiceLocked方法。而mServices对象是ActiveServices类型的。所以ActiveServices的bindServiceLocked方法如下所示。

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, final IServiceConnection connection, int flags,
        String callingPackage, final int userId) throws TransactionTooLargeException {
    ...省略

    ServiceLookupResult res =
        retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
                Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
    ...省略
    //记住ServiceRecord这个对象,特别重要
    ServiceRecord s = res.record;

    boolean permissionsReviewRequired = false;

    // If permissions need a review before any of the app components can run,
    // we schedule binding to the service but do not start its process, then
    // we launch a review activity to which is passed a callback to invoke
    // when done to start the bound service's process to completing the binding.
    if (mAm.mPermissionReviewRequired) {
        if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                s.packageName, s.userId)) {

            permissionsReviewRequired = true;

            final ServiceRecord serviceRecord = s;
            final Intent serviceIntent = service;

            RemoteCallback callback = new RemoteCallback(
                    new RemoteCallback.OnResultListener() {
                @Override
                public void onResult(Bundle result) {
                    synchronized(mAm) {
                        final long identity = Binder.clearCallingIdentity();
                        try {
                            if (!mAm.getPackageManagerInternalLocked()
                                    .isPermissionsReviewRequired(
                                            serviceRecord.packageName,
                                            serviceRecord.userId)) {
                                try {
                                    //这里的serviceRecord对象就是上面的s
                                    bringUpServiceLocked(serviceRecord,
                                            serviceIntent.getFlags(),
                                            callerFg, false, false);
                                } catch (RemoteException e) {
                                    /* ignore - local call */
                                }
                            } else {
                                unbindServiceLocked(connection);
                            }
                        } finally {
                            Binder.restoreCallingIdentity(identity);
                        }
                    }
                }
            });

            mAm.mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
                }
            });
        }
    }

    final long origId = Binder.clearCallingIdentity();

    try {     
        if ((flags&Context.BIND_AUTO_CREATE) != 0) {
            s.lastActivity = SystemClock.uptimeMillis();
            if (!s.hasAutoCreateConnections()) {
                // This is the first binding, let the tracker know.
                ServiceState stracker = s.getTracker();
                if (stracker != null) {
                    stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
                            s.lastActivity);
                }
            }
        }

        mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState,
                s.appInfo.uid, s.name, s.processName);
        // Once the apps have become associated, if one of them is caller is ephemeral
        // the target app should now be able to see the calling app
        mAm.grantEphemeralAccessLocked(callerApp.userId, service,
                s.appInfo.uid, UserHandle.getAppId(callerApp.uid));

        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
        //记住这个ConnectionRecord对象,后面绑定Service对象时会出现该对象
        //这个ConnectionRecord对象存储了connection对象,即IServiceConnection对象。
        ConnectionRecord c = new ConnectionRecord(b, activity,
                connection, flags, clientLabel, clientIntent);
        //这里的connection是ServiceDispatcher的内部类InnerConnection,而InnerConnection继承了IServiceConnection.Stub
        IBinder binder = connection.asBinder();
        //s是ServiceRecord类型的对象,不要忘记了。
        //s.connections是一个ArrayMap对象,它存储了一个ArrayList,这里的ArrayList是clist。
        //而clist又存储了ConnectionRecord对象。而ConnectionRecord对象又存储了connection参数。
        //而connection参数是一个IServiceConnection对象,也就是上面说过的InnerConnection对象。
        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            s.connections.put(binder, clist);
        }
        clist.add(c);
        b.connections.add(c);
        if (activity != null) {
            if (activity.connections == null) {
                activity.connections = new HashSet<ConnectionRecord>();
            }
            activity.connections.add(c);
        }
        b.client.connections.add(c);
        if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
            b.client.hasAboveClient = true;
        }
        if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
            s.whitelistManager = true;
        }
        if (s.app != null) {
            updateServiceClientActivitiesLocked(s.app, c, true);
        }
        clist = mServiceConnections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            mServiceConnections.put(binder, clist);
        }
        clist.add(c);

        if ((flags&Context.BIND_AUTO_CREATE) != 0) {
            s.lastActivity = SystemClock.uptimeMillis();
            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                    permissionsReviewRequired) != null) {
                return 0;
            }
        }

        ...省略

        if (s.app != null && b.intent.received) {
            // Service is already running, so we can immediately
            // publish the connection.
            try {
                c.conn.connected(s.name, b.intent.binder, false);
            } catch (Exception e) {
                Slog.w(TAG, "Failure sending service " + s.shortName
                        + " to connection " + c.conn.asBinder()
                        + " (in " + c.binding.client.processName + ")", e);
            }

            // If this is the first app connected back to this binding,
            // and the service had previously asked to be told when
            // rebound, then do so.
            if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                requestServiceBindingLocked(s, b.intent, callerFg, true);
            }
        } else if (!b.intent.requested) {
            requestServiceBindingLocked(s, b.intent, callerFg, false);
        }

        getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);

    } finally {
        Binder.restoreCallingIdentity(origId);
    }

    return 1;
}

在ActiveServices的bindServiceLocked方法中,又调用了ActiveServices的内部方法——bringUpServiceLocked,而bringUpServiceLocked又调用了realStartServiceLocked方法,如下所示。

private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
    ...省略
    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

    final boolean newService = app.services.add(r);
    bumpServiceExecutingLocked(r, execInFg, "create");
    mAm.updateLruProcessLocked(app, false, null);
    updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
    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);
        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);

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

    sendServiceArgsLocked(r, execInFg, true);

    if (r.delayed) {
        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) {
        // 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);
        }
    }
}

上面的代码中,通过app.thread对象的scheduleCreateService方法创建了Service对象。我们已经知道app.thread是ActivityThread对象,所以这里是调用了ActivityThread的scheduleCreateService方法,如下所示。

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

这个scheduleCreateService方法和上面我们分析的启动状态的Service的创建方法是一样的,最后都是通过反射的形式创建了Service对象,并调用了Service对象的attach、onCreate等生命周期方法。

如果仅到此为止,启动状态的Service和绑定状态的Service就没什么区别了。但是既然官方给定了两种不同状态的Service,它们之间肯定存在着区别的。

我们回溯到之前已经分析过的代码,终于在ActiveServices的realStartServiceLocked方法中看到,它在执行了app.thread.scheduleCreateService创建Service对象后,接着执行了requestServiceBindingsLocked方法,如下所示。

private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
        throws TransactionTooLargeException {
    for (int i=r.bindings.size()-1; i>=0; i--) {
        IntentBindRecord ibr = r.bindings.valueAt(i);
        if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
            break;
        }
    }
}

Note:启动状态的Service也会调用requestServiceBindingsLocked这个方法,但是其中的r.bindings.size为空,因此不能往下执行逻辑。

对于绑定状态的Service来说,ActiveServices的requestServiceBindingsLocked方法中又执行了ActiveServices的requestServiceBindingLocked方法,如下所示。

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
        boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    ...省略
    if ((!i.requested || rebind) && i.apps.size() > 0) {
        try {
            bumpServiceExecutingLocked(r, execInFg, "bind");
            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            //绑定Service对象
            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                    r.app.repProcState);
            if (!rebind) {
                i.requested = true;
            }
            i.hasBound = true;
            i.doRebind = false;
        } catch (TransactionTooLargeException e) {
            
        } catch (RemoteException e) {
            
        }
    }
    return true;
}

上面的代码中调用了r.app.thread的scheduleBindService方法,而r.app.thread是一个ActivityThread对象,其中的scheduleBindService方法如下所示。

public final void scheduleBindService(IBinder token, Intent intent,
        boolean rebind, int processState) {
    updateProcessState(processState, false);
    BindServiceData s = new BindServiceData();
    s.token = token;
    s.intent = intent;
    s.rebind = rebind;

    sendMessage(H.BIND_SERVICE, s);
}

scheduleBindService方法通过调用sendMessage方法,发送了一个消息给ActivityThread的内部类H处理,其处理逻辑如下所示。

case BIND_SERVICE:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
    handleBindService((BindServiceData)msg.obj);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;

在内部类H的handleMessage方法中,对于H.BIND_SERVICE的处理是调用了handleBindService方法,如下所示。

private void handleBindService(BindServiceData data) {
	//从mServices获取上面创建的Service对象
    Service s = mServices.get(data.token); 
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            try {
                if (!data.rebind) { //第一次绑定时的逻辑
                	//执行Service对象的onBind方法,onBind方法返回一个IBinder对象
                    IBinder binder = s.onBind(data.intent);
                    //将onBind方法返回的IBinder对象作为参数,调用AMS的publishService方法
                    ActivityManager.getService().publishService(
                            data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                }
                ensureJitEnabled();
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            
        }
    }
}

handleBindService方法主要做了以下几件事: 1、从mServices这个变量中获取一个Service对象,该Service对象就是我们上面创建过的。 2、调用Service对象的onBind方法,该方法返回了一个IBinder对象。该IBinder对象可以简单理解为是Service的逻辑处理。 3、调用了ActivityManagerService(AMS)的publishService方法,将该IBinder对象作为参数传递进去。 我们接着看AMS的publishService方法,如下所示。

public void publishService(IBinder token, Intent intent, IBinder service) {
    ...省略
    synchronized(this) {
        if (!(token instanceof ServiceRecord)) {
            throw new IllegalArgumentException("Invalid service token");
        }
        mServices.publishServiceLocked((ServiceRecord)token, intent, service);
    }
}

上面的代码中调用了ActiveServices的publishServiceLocked方法,如下所示。

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    final long origId = Binder.clearCallingIdentity();
    try {
        if (r != null) {
            Intent.FilterComparison filter
                    = new Intent.FilterComparison(intent);
            IntentBindRecord b = r.bindings.get(filter);
            if (b != null && !b.received) {
                b.binder = service;
                b.requested = true;
                b.received = true;
                //ServiceRecord的connections是一个ArrayMap对象。
                //遍历该ArrayMap对象的Value值,Value值是一个ArrayList对象
                //遍历ArrayList对象,获取每一个ConnectionRecord对象,通过filter找到
                //相应的ConnectionRecord对象
                for (int conni=r.connections.size()-1; conni>=0; conni--) {
                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                    for (int i=0; i<clist.size(); i++) {
                        ConnectionRecord c = clist.get(i);
                        if (!filter.equals(c.binding.intent.intent)) {
                            continue;
                        }
                        try {
                            //c是ConnectionRecord对象,其中的conn是InnerConnection
                            //对象,这里实际上是调用了InnerConnection的connected方法。
                            c.conn.connected(r.name, service, false);
                        } catch (Exception e) {
                        }
                    }
                }
            }

            serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
}

上面的注释提到,在try方法块中调用了c.conn对象的connected方法,而c.conn对象是InnerConnection对象。所以我们转到InnerConnection对象的connected方法,如下所示。

public void connected(ComponentName name, IBinder service, boolean dead)
        throws RemoteException {
    LoadedApk.ServiceDispatcher sd = mDispatcher.get();
    if (sd != null) {
        sd.connected(name, service, dead);
    }
}

上面的代码首先通过mDispatcher对象获取了LoadedApk的内部类ServiceDispatcher对象,然后调用了该对象的connected方法。如下所示。

public void connected(ComponentName name, IBinder service, boolean dead) {
    if (mActivityThread != null) {
        mActivityThread.post(new RunConnection(name, service, 0, dead));
    } else {
        doConnected(name, service, dead);
    }
}   

上面的connected方法中有两个分支,而不论哪个分支,最终都会执行到doConnected方法,所以我们直接看doConnected方法的逻辑,如下所示。

public void doConnected(ComponentName name, IBinder service, boolean dead) {
    ServiceDispatcher.ConnectionInfo old;
    ServiceDispatcher.ConnectionInfo info;

    synchronized (this) {
        old = mActiveConnections.get(name);
        //Service已经绑定过了
        if (old != null && old.binder == service) {
            // Huh, already have this one.  Oh well!
            return;
        }
        //将新的Service信息存储起来
        if (service != null) {
            info = new ConnectionInfo();
            info.binder = service;
            info.deathMonitor = new DeathMonitor(name, service);
            try {
                service.linkToDeath(info.deathMonitor, 0);
                mActiveConnections.put(name, info);
            } catch (RemoteException e) {
                mActiveConnections.remove(name);
                return;
            }
        } else {
            mActiveConnections.remove(name);
        }
        if (old != null) {
            old.binder.unlinkToDeath(old.deathMonitor, 0);
        }
    }

    ///将旧的Service进行解绑的操作
    if (old != null) {
        mConnection.onServiceDisconnected(name);
    }
    if (dead) {
        mConnection.onBindingDied(name);
    }
    //调用mConnection对象的onServiceConnected方法绑定新的Service
    //这里的mConnection就是ServiceConnection对象,也即是我们最开始调用bindService方法时
    //传进来的参数。这里的service参数就是Service服务的onBind方法返回的IBinder对象。
    if (service != null) {
        mConnection.onServiceConnected(name, service);
    }
}

上面的代码中,如果是第一次连接,会走到最后的mConnection的onServiceConnected方法。这里的mConnection对象就是ServiceConnection对象,也就是我们最开始调用bindService传进来的参数。

这里看一个调用bindService方法的小例子:

bindService(intent, new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        bookManager = IBookManager.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        bookManager = null;
    }
}, BIND_AUTO_CREATE);

可以看到ServiceConnection的onServiceConnected方法,传进来的第二个参数service是IBinder对象,也就是我们上面分析的Service的onBind方法返回的IBinder对象。通过该IBinder对象,我们可以实现Activity和Service(本地Service或者远程Service)之间的交互。

至此,Service的两种状态的工作过程都分析完毕了。这里先抛出两个问题流到后续再讨论: 1、为什么使用bindService方法时,Activity和Service是绑定起来的,当Activity被销毁,Service也会跟着被销毁? 2、Activity和Service的交互,Service可以是本地的或者是跨进程的,两者之间有什么区别?