Service(三)--bindService()

727 阅读2分钟

这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

一、bindService()调用过程

bindService()绑定一个Service时,最终都会调用的ContextWrapper的bindService()方法

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

我们之前讲过mBase是ContextImpl,我们来看看ContextImpl里面的bindService()方法

@Override
public boolean bindService(Intent service, ServiceConnection conn,int flags) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(...);

我们接着到 bindServiceCommon里面看看,在bindServiceCommon会调用ActivityManagerService的bindService()方法,但是在这之前,会获取一个IServiceConnection对象(也就是ServiceDispatch.InnerConnection类的对象),来实现跨进程通信

private boolean bindServiceCommon(...) {
    ...
    IServiceConnection sd;
    if (mPackageInfo != null) {
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    }
    ...
    try {
        ...
        int res = ActivityManager.getService().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());
        ...
    } 
}

ActivityManagerService的bindService()方法中会调到bringUpServiceLocked()方法,在这里面有个realStartServiceLocked()

private String bringUpServiceLocked(...)...{
    ...    
    try {
        realStartServiceLocked(r, app, execInFg);
                return null;
    } 
    ...
}

realStartServiceLocked()方法中通过调用ActivityThread中ApplicationThread的scheduleCreateService()方法,真正执行了Service的创建过程,即onCreate(),然后调用requestServiceBindingsLocked()方法

private final void realStartServiceLocked(...)...{
    ...
    app.thread.scheduleCreateService(r, r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);
    ...
    requestServiceBindingsLocked(r, execInFg);
}

在requestServiceBindingsLocked()方法中去调用ActivityThread中ApplicationThread的scheduleBindService()方法来执行Service的bind过程,即onBind()

private final boolean requestServiceBindingLocked(...)...{
    ...
    r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState);
   ...
}

后面就是调用ActivityManagerService的publishService(),然后调用publishServiceLocked()方法,在这个方法中会调用ServiceDispatch.InnerConnection的connected()方法,最终回调ServiceConnection的onServiceConnected()方法

一、bindService()总结

  • bindService()即绑定服务,会建立一个逻辑连接。当连接建立之后,AMS会回调ServiceConnection接口对象的onServiceConnected()方法。把远端service的代理binder传递过来,这样就可以通过这个代理binder跨进程调用service中的方法了。
  • bindService的过程,我们要关心的binder有两个,一个是远端service的binder,有了它客户端进程才能跨进程调用service中的方法;另一个是binder是客户端传递给AMS的,有了这个binder,AMS才会在逻辑连接建立之后,跨进程调用客户端中的ServiceConnection接口的对象中的onServiceConnected()和onServiceDisconnected()
  • 只有在绑定这个service的所有客户端中的组件都执行了unbindeService()时,service才会被销毁,执行servcice.onDestroy()