Service的工作过程

860 阅读7分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情

Service有两种状态,一种是启动状态主要用于执行后台计算,另一种是绑定状态,主要用于其他组件与Service之间的交互,两种状态是可以共存的。

1.Service的启动过程

Service的启动过程要从startService看起

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

代码中的mBase的原型是Context的实现类ContextImpl,在Activity创建时会通过attach方法将一个ContextImpl对象关联起来,这个ContextImpl就是代码中的mBase,从ContextWrapper代码中可以看出里面的大多数操作都是通过mBase完成的,这是一种桥接模式, 继续看ContextImpl中的startService

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

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

在ContextImpl中的startService进入到startServiceCommon,然后倒了ActivityManager.getService().startService()

这里先分析一下ActivityManager.getService()

//ActivityManager#getService
@UnsupportedAppUsage
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

@UnsupportedAppUsage
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;
    }
};

看到Binder就可以明白这里是一个获取跨进程服务,获取的服务是ActivityManagerService(AMS),它继承自IActivityManager.Stub,是个Binder对象,通过单例提供服务。AMS运行在系统进程中(system_server),到这里原本运行在客户端的startService就转移到了AMS中运行,看一下AMS中startService的实现

//ActivityManagerService#startService
@Override
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;
    }
}

上面的代码中会通过mService对象来完成Service后续的启动过程,mService的类型是ActiveServices,它辅助AMS管理Service,包括Service的启动、绑定、停止等,在ActiveServices的startServiceLocked的方法中又进入了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);
    }
    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();
    }
    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;
}

在startServiceInnerLocked的参数中有一个ServiceRecord对象,ServiceRecord描述的是一个Service记录,它贯穿整个Service的启动过程。在startServiceInnerLocked并没有完成Service的启动,而是交给了bringUpServiceLocked,在bringUpServiceLocked方法中又调用了realStartServiceLocked,由这个方法完成Service的启动

//AcyiveServices#realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,
                                          ProcessRecord app, boolean execInFg) throws RemoteException {
    if (app.thread == null) {
        throw new RemoteException();
    }
    ...
    
    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());
      
	...

    sendServiceArgsLocked(r, execInFg, true);

	...
}

在realStartServiceLocked方法中首先通过app.thread.scheduleCreateService创建Service对象并调用它的onCreate方法,然后再通过sendServiceArgsLocked方法来调用Service的其他方法如startServiceCommand,这两个过程均是进程间的通信。app.thread对象是IApplicationThread类型,它实际上是一个Binder,它的具体实现是ApplicationThread,因为ApplicationThread是ActivityThread的内部类因此进入ActivityThread中的ApplicatonThread中查看scheduleCreateService的实现

//ActivityThread#ApplicationThread#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中的实现与Activity的启动类似,都是通过把消息发送到Handler的实现类H来完成的,最终交给handleCreateService来完成

//ActivityThread#handleCreateService
@UnsupportedAppUsage
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 {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = packageInfo.getAppFactory()
            .instantiateService(cl, data.info.name, data.intent);
    } 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);

        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);

        Application app = packageInfo.makeApplication(false, mInstrumentation);
        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);
        }
    }
}

handleCreateService主要做了几件事:

    • 通过类加载器创建Service实例
    • 创建ContextImpl对象
    • 创建Application对象并调用它的onCreate方法
    • 通过Service的attach方法建立ContextImpl、Application与Service之间的关系
    • 最后调用Service的onCreate方法并将Service对象存储到ActivityThread中的一个列表中,列表定义如下:

final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();

Service的onCreate方法执行了也就意味着Service已经启动了,除此之外ActivityThread中还会通过handleServiceArgs方法调用Service的onStartCommand方法。

//ActivityThread#onStartCommand
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);
            }
        }
    }
}

2.Service的绑定过程

Service的绑定过程也是从ContextWrapper开始的

//ContextWrapper
@Override
public boolean bindService(Intent service, ServiceConnection conn,
                           int flags) {
    return mBase.bindService(service, conn, flags);
}

mBase也是ContextImpl然后进入ContextImpl的bindService

//ContextImpl#bindService
@Override
public boolean bindService(
    Intent service, int flags, Executor executor, ServiceConnection conn) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(service, conn, flags, null, null, executor, getUser());
}

//ContextImpl#bindServiceCommon
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
                                  String instanceName, Handler handler, Executor executor, UserHandle user) {
    // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
    IServiceConnection sd;
    if (conn == null) {
        throw new IllegalArgumentException("connection is null");
    }
    if (handler != null && executor != null) {
        throw new IllegalArgumentException("Handler and Executor both supplied");
    }
    if (mPackageInfo != null) {
        if (executor != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
        } else {
            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);
        int res = ActivityManager.getService().bindIsolatedService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, instanceName, 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();
    }
}

bindServiceCommon主要做了两件事情,第一件事情就是把ServiceConnection对象转化为ServiceDispatcher.InnerConnection,那么为什么不直接使用ServiceConnection对象呢,这是因为服务的绑定有可能是跨进程的,因此ServiceConnection必须借助Binder才能让远程服务端回调自己的方法,而ServiceDispatcher的内部类InnerConnection正好充当了这个角色,InnerConnection继承自IServiceConnection.Stub。进入方法getServiceDispatcher()分析

//LoadApk#getServiceDispatcher
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
                                                     Context context, Executor executor, int flags) {
    return getServiceDispatcherCommon(c, context, null, executor, flags);
}

//LoadApk#getServiceDispatcherCommon
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
                                                      Context context, Handler handler, Executor executor, int flags) {
    synchronized (mServices) {
        LoadedApk.ServiceDispatcher sd = null;
        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
        if (map != null) {
            if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
            sd = map.get(c);
        }
        if (sd == null) {
            if (executor != null) {
                sd = new ServiceDispatcher(c, context, executor, flags);
            } else {
                sd = new ServiceDispatcher(c, context, handler, flags);
            }
            if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
            if (map == null) {
                map = new ArrayMap<>();
                mServices.put(context, map);
            }
            map.put(c, sd);
        } else {
            sd.validate(context, handler, executor);
        }
        return sd.getIServiceConnection();
    }
}

在getServiceCommon方法中实例化了ServiceDispatcher,它的作用是连接ServiceConnection和InnerConnection。

上面代码中的mServices是一个ArrayMap,定义如下

private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
        = new ArrayMap<>();

mService.put(context, map);//这里的map定义如下
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
//LoadApk#ServiceDispatcher
ServiceDispatcher(ServiceConnection conn,
                  Context context, Executor activityExecutor, int flags) {
    mIServiceConnection = new InnerConnection(this);
    mConnection = conn;
    mContext = context;
    mActivityThread = null;
    mActivityExecutor = activityExecutor;
    mLocation = new ServiceConnectionLeaked(null);
    mLocation.fillInStackTrace();
    mFlags = flags;
}

这个mService存储的是一个应用当前活动的ServiceConnection和ServiceDispatcher的映射关系。系统会首先查找是否存在相同的ServiceConnection,如果不存在就重新创建一个新的ServiceDispatcher对象并将其存储在mService中,其映射关系的key是ServiceConnection,value是ServiceDispatcher。ServiceDispatcher对象的内部存储了ServiceConnection和InnerConnection,当Service和客户端建立连接后,系统会通过InnerConnection来调用ServiceConnection中的onServiceConnected方法,这个过程有可能是跨进程的。当ServiceDispatcher创建好了以后就会通过getServiceDispatcher会返回其保存的InnerConnection对象。

//这是调用onServiceConnected的方法调用关系
private static class InnerConnection extends IServiceConnection.Stub {
    @UnsupportedAppUsage
    final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

    InnerConnection(LoadedApk.ServiceDispatcher sd) {
        mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
    }

    public void connected(ComponentName name, IBinder service, boolean dead)
        throws RemoteException {
      	
		sd.connected(name, service, dead);  
    }
}

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

public void doConnected(ComponentName name, IBinder service, boolean dead) {
    ...
        // If there is a new viable service, it is now connected.
        if (service != null) {
            mConnection.onServiceConnected(name, service);
        } else {
            // The binding machinery worked, but the remote returned null from onBind().
            mConnection.onNullBinding(name);
        }
}

当bindServiceCommon方法中的getServiceDispatcher返回后就要完成第二件事情,这里进入ActivityManager.getService.bindIsoatedService()

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

@UnsupportedAppUsage
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;
    }
};

这里回到了AMS中,那么查看AMS中的bindIsolatedService做了什么

//ActivityManagerService#bindIsolatedService
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
                               String resolvedType, IServiceConnection connection, int flags, String instanceName,
                               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");
    }

    // Ensure that instanceName, which is caller provided, does not contain
    // unusual characters.
    if (instanceName != null) {
        for (int i = 0; i < instanceName.length(); ++i) {
            char c = instanceName.charAt(i);
            if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                  || (c >= '0' && c <= '9') || c == '_' || c == '.')) {
                throw new IllegalArgumentException("Illegal instanceName");
            }
        }
    }

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

这里的mServices是ActiveServices,这里进入了ActivityServices的bindServiceLocked方法中,在这个方法中又进入了requestServiceBindingLocked方法

//AcyiveServices#requestServiceBindingLocked
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
                                                  boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    if (r.app == null || r.app.thread == null) {
        // If service is not currently running, can't yet bind.
        return false;
    }
    if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested
                              + " rebind=" + rebind);
    if ((!i.requested || rebind) && i.apps.size() > 0) {
        try {
            bumpServiceExecutingLocked(r, execInFg, "bind");
            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                                             r.app.getReportedProcState());
            if (!rebind) {
                i.requested = true;
            }
            i.hasBound = true;
            i.doRebind = false;
        } catch (TransactionTooLargeException e) {
            // Keep the executeNesting count accurate.
            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
            throw e;
        } catch (RemoteException e) {
            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
            // Keep the executeNesting count accurate.
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
            return false;
        }
    }
    return true;
}

在requestServiceBindingLocked方法中通过app.thread调用了scheduleBindService方法,这里app.thread是IApplicationThread,它的实现类是ApplicationThread,所以scheduleBindService进入到ActivityThread的内部类ApplicationThread中分析

//ActivityThread#ApplicationThread#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;

    if (DEBUG_SERVICE)
        Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
               + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
    sendMessage(H.BIND_SERVICE, s);
}

可以看到这里还是通过sendMessage发送了消息,这个H同样是Handler的实现类,这里就直接进入处理BIND_SERVICE的方法handleBindService中分析

//ActivityThread#handBindService
private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (DEBUG_SERVICE)
        Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            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();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                    "Unable to bind to service " + s
                    + " with " + data.intent + ": " + e.toString(), e);
            }
        }
    }
}

在handleBindService方法中首先根据Service的token出Service的对象,然后调用onBind方法返回一个Bidner对象给客户端使用。理论上当onBind方法被调用以后Service就处于绑定状态了,但是客户端并不知道,所以还要调用客户端的onServiceConnected方法,这个方法在ServiceConnection中,这个过程是由ActivityManager.getService().publishService完成的,getService这里不再分析直接进入publishService的方法分析

//ActivityManagerService#publishService
public void publishService(IBinder token, Intent intent, IBinder service) {
    // Refuse possible leaked file descriptors
    if (intent != null && intent.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }

    synchronized(this) {
        if (!(token instanceof ServiceRecord)) {
            throw new IllegalArgumentException("Invalid service token");
        }
        mServices.publishServiceLocked((ServiceRecord)token, intent, service);
    }
}

//ActivityServices#publishServiceLocked
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    final long origId = Binder.clearCallingIdentity();
    try {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
                                  + " " + intent + ": " + service);
        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;
                ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
                for (int conni = connections.size() - 1; conni >= 0; conni--) {
                    ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                    for (int i=0; i<clist.size(); i++) {
                        ConnectionRecord c = clist.get(i);
                        if (!filter.equals(c.binding.intent.intent)) {
                            if (DEBUG_SERVICE) Slog.v(
                                TAG_SERVICE, "Not publishing to: " + c);
                            if (DEBUG_SERVICE) Slog.v(
                                TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
                            if (DEBUG_SERVICE) Slog.v(
                                TAG_SERVICE, "Published intent: " + intent);
                            continue;
                        }
                        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                        try {
                            c.conn.connected(r.name, service, false);
                        } catch (Exception e) {
                            Slog.w(TAG, "Failure sending service " + r.shortInstanceName
                                   + " to connection " + c.conn.asBinder()
                                   + " (in " + c.binding.client.processName + ")", e);
                        }
                    }
                }
            }

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

publishServiceLocked方法中只需要关心一行代码c.conn.connected(r.name,service,false);这里的c是ConnectionRecord,c.conn是ServiceDispatcher.InnerConnection,参数中的service就是onBind方法返回的Binder对象,这里先看一下ServiceDispatcher.InnerConnection

//LoadApk#ServiceDispatcher#InnerConnection
private static class InnerConnection extends IServiceConnection.Stub {
    @UnsupportedAppUsage
    final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

    InnerConnection(LoadedApk.ServiceDispatcher sd) {
        mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
    }

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

这里的sd是ServiceDispatcher,sd.connected就是调用了ServiceDispatcher中的connected方法,然后在connected方法中进入了doConnected方法

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

//LoadApk#doConnected
public void doConnected(ComponentName name, IBinder service, boolean dead) {
  	...
    // If there is a new viable service, it is now connected.
    if (service != null) {
        mConnection.onServiceConnected(name, service);
    } else {
        // The binding machinery worked, but the remote returned null from onBind().
        mConnection.onNullBinding(name);
    }
}

在doConnected方法中mConnection.onServiceConnected执行后Service的绑定过程也就分析完了,还要说明一下mConnection,在ServiceDispatcher内部保存了客户端的serviceConnection对象因此也就可以很方便的调用onServiceConnected方法。