Service绑定形式启动过程

一、绑定形式Service的使用
1)定义一个Service,注意重写onBind方法,返回一个IBinder对象

public class MyService extends Service {
    public static final String LOG_TAG = "LOG_TAG";

    private MyBinder mBinder = new MyBinder();

    public class MyBinder extends Binder {
        public MyService getService() {
            return MyService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(LOG_TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(LOG_TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(LOG_TAG, "onBind");
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(LOG_TAG, "onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(LOG_TAG, "onDestroy");
    }
}


2)注意在manifest中注册service

<service android:name=".MyService"/>
 

3)在Activity中bindService:

public class ServiceActivity extends AppCompatActivity {
    private MyService mService;

    // 定义ServiceConnection
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 通过定义的Binder来获取Service实例来供使用
            mService = ((MyService.MyBinder) service).getService();
            Log.w(MyService.LOG_TAG, "Activity onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mService = null;
            // 当Service被意外销毁时
            Log.w(MyService.LOG_TAG, "Activity onServiceDisconnected");
        }
    };

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

    @Override
    protected void onResume() {
        super.onResume();
        // bindService
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
        Log.w(MyService.LOG_TAG, "Activity bindService");
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 进行unbind
        unbindService(conn);
        Log.w(MyService.LOG_TAG, "Activity unbindService");
    }
}

二、Service绑定形式源码分析
1)ContextWrapper#bindService:

/** @path: \frameworks\base\core\java\android\content\ContextWrapper.java **/
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    // @value Context mBase;
    return mBase.bindService(service, conn, flags);
}
和启动形式相仿,接下来调用ContextImpl.bindService;


2) ContextImpl#bindService:

/** @path: \frameworks\base\core\java\android\app\ContextImpl.java**/
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}

3) ContextImpl#bindServiceCommon:

/** @path: \frameworks\base\core\java\android\app\ContextImpl.java**/
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
                                  UserHandle user) {
    IServiceConnection sd;
    if (conn == null) {
        throw new IllegalArgumentException("connection is null");
    }
    if (mPackageInfo != null) {
        // 将ServiceConnection封装成为IServiceConnection
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
                mMainThread.getHandler(), 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
                < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            flags |= BIND_WAIVE_PRIORITY;
        }
        service.prepareToLeaveProcess();
        // 调用bindService来绑定启动Service
        int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(),
                service, service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, user.getIdentifier());
        if (res < 0) {
            throw new SecurityException(
                    "Not allowed to bind to service " + service);
        }
        return res != 0;
    } catch (RemoteException e) {
        return false;
    }
}
代码中首先将ServiceConnection对象转化成为IServiceConnection。因为Service与客户端建立的连接,可能是跨进程的,系统在绑定Service过程中可能通过IServiceConnection来调用ServiceConnection中的onServiceConnection方法,该过程可能是跨进程的,IServiceConnection是个AIDL文件;

之后再通过ActivityManagerNative.getDefault().bindService来开始绑定Service操作。


先来看第一步,由于mPackageInfo的类型为LoadedApk;
final LoadedApk mPackageInfo;
3.1)LoadedApk#getServiceDispatcher:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/
public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags) {
    synchronized (mServices) {
        ServiceDispatcher sd = null;
        // 以ServiceConnection为关键字,将ServiceDispatcher与erviceConnection建立关联保存起来
        // 还可以看到保存的ArrayMap最终会以Context为关键字保存在一个变量mServices中
        /** @value :private final ArrayMap<Context, ArrayMap<ServiceConnection, ServiceDispatcher>> mServices
                                 = new ArrayMap<Context, ArrayMap<ServiceConnection, ServiceDispatcher>>();**/
        ArrayMap<ServiceConnection, ServiceDispatcher> map = mServices.get(context);
        // 先尝试进行获取
        if (map != null) {
            sd = map.get(c);
        }
        // 如果已存在直接返回,未存在则进行创建
        if (sd == null) {
            // 创建一个新的ServiceDispatcher
            sd = new ServiceDispatcher(c, context, handler, flags);
            // 如果map为空,则创建一个ArrayMap并保存到mServices中
            if (map == null) {
                map = new ArrayMap<ServiceConnection, ServiceDispatcher>();
                mServices.put(context, map);
            }
            // 将对应的ServiceConnection与ServiceDispatcher保存到一个map中
            map.put(c, sd);
        } else {
            sd.validate(context, handler);
        }
        // 返回一个IServiceConnection类型
        return sd.getIServiceConnection();
    }
}
方法中的参数:

ServiceConnection c  == 即Service中自定义的ServiceConnection对象

Context context         == 传入的为getOuterContext(),即mOuterContext,ContextImpl类型,指向一个Activity组件

Handler handler        == 传入参数为mMainThread.getHandler();

mMainThread的类型为ActivityThread:

final ActivityThread mMainThread;
/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
final H mH = new H();
final Handler getHandler() {
    return mH;
}
可以看到最终用来发送启动service消息到主线程的Handler H。

继续来看sd.getIServiceConnection();ServiceDispatcher是LoadedApk的内部类。

先来看ServiceDispatcher的构造函数:

3.2)LoadedApk#ServiceDispatcher#ServiceDispatcher:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/
static final class ServiceDispatcher {
    private final InnerConnection mIServiceConnection;
    private final ServiceConnection mConnection;
    private final Context mContext;
    private final Handler mActivityThread;
    private final ServiceConnectionLeaked mLocation;
    private final int mFlags;

    private static class InnerConnection extends IServiceConnection.Stub {
        final WeakReference<ServiceDispatcher> mDispatcher;

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

        public void connected(ComponentName name, IBinder service) throws RemoteException {
            ServiceDispatcher sd = mDispatcher.get();
            if (sd != null) {
                sd.connected(name, service);
            }
        }
    }
    
    ServiceDispatcher(ServiceConnection conn, Context context, Handler activityThread, int flags) {
        mIServiceConnection = new InnerConnection(this);
        mConnection = conn;
        mContext = context;
        mActivityThread = activityThread;
        mLocation = new ServiceConnectionLeaked(null);
        mLocation.fillInStackTrace();
        mFlags = flags;
    }
}
    可以看到InnerConnection继承了IServiceConnection.Stub,IServiceConnection是个aidl,因此将本地的ServiceConnection封装成为ServiceDispatcher#InnerConnection,可以用以进程间的通信。


3.3)LoadedApk#ServiceDispatcher#getIServiceConnection:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/
static final class ServiceDispatcher {
    private final InnerConnection mIServiceConnection;
    IServiceConnection getIServiceConnection() {
        return mIServiceConnection;
    }
}
getIServiceConnection逻辑较为简单,即是返回新创建的InnerConnection,因此sd的编译时类型为IServiceConnection,运行时类型为ServiceDispatcher.InnerConnection:


分析完ServiceConnection,下面接着分析ActivityManagerNative.getDefault().bindService,由前面得知ActivityManagerNative.getDefault()的类型为AMS的代理:ActivityManagerProxy;则下面调用的是ActivityManagerProxy.bindService;

4、ActivityManagerProxy#bindService:
调用:

ActivityManagerNative.getDefault().bindService(
        mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, user.getIdentifier());
源代码: 

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager {
    public int bindService(IApplicationThread caller, IBinder token,
                           Intent service, String resolvedType, IServiceConnection connection,
                           int flags, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeStrongBinder(token);
        service.writeToParcel(data, 0);
        data.writeString(resolvedType);
        // 可以看到将ServiceConnection写入到data中,发送给AMS
        data.writeStrongBinder(connection.asBinder());
        data.writeInt(flags);
        data.writeInt(userId);
        // 发送BIND_SERVICE_TRANSACTION IPC通信请求
        mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        int res = reply.readInt();
        data.recycle();
        reply.recycle();
        return res;
    }
}
将前面获取到的sd以Binder方式发送给AMS,并发送 BIND_SERVICE_TRANSACTION IPC通信请求。

接下来到ActivityManagerNative中去处理:


5、ActivityManagerNative#onTransact:

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
public abstract class ActivityManagerNative extends Binder implements IActivityManager {
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
            case BIND_SERVICE_TRANSACTION: {
                data.enforceInterface(IActivityManager.descriptor);
                IBinder b = data.readStrongBinder();
                IApplicationThread app = ApplicationThreadNative.asInterface(b);
                IBinder token = data.readStrongBinder();
                Intent service = Intent.CREATOR.createFromParcel(data);
                String resolvedType = data.readString();
                b = data.readStrongBinder();
                int fl = data.readInt();
                int userId = data.readInt();
                IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
                // 处理IPC请求函数
                int res = bindService(app, token, service, resolvedType, conn, fl, userId);
                reply.writeNoException();
                reply.writeInt(res);
                return true;
            }
        }
    }
}
接下来使用ActivityManagerNative的子类ActivityManagerService来具体处理该应用请求:


6、ActivityManagerService#bindService:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/
public int bindService(IApplicationThread caller, IBinder token,
                       Intent service, String resolvedType,
                       IServiceConnection connection, int flags, int userId) {
    enforceNotIsolatedCaller("bindService");

    // Refuse possible leaked file descriptors
    if (service != null && service.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }

    synchronized(this) {
        return mServices.bindServiceLocked(caller, token, service, resolvedType,
                connection, flags, userId);
    }
}
和启动形式一样,最后交给ActiveServices去处理;


7、ActiveServices#bindServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
int bindServiceLocked(IApplicationThread caller, IBinder token,
                      Intent service, String resolvedType,
                      IServiceConnection connection, int flags, int userId) {
    // 该ProcessRecord描述的是请求绑定该Service组件的Activity组件所运行的应用进程
    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);

    // 获得ActivityRecord用来描述该Activity组件
    ActivityRecord activity = null;
    if (token != null) {
        activity = ActivityRecord.isInStackLocked(token);
        if (activity == null) {
            return 0;
        }
    }

    .....

    // 将待启动的Service组件信息封装成ServiceLookupResult
    ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType,
                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
    .....
    // ServiceRecord用来记录该Service组件的相关信息
    ServiceRecord s = res.record;

    final long origId = Binder.clearCallingIdentity();

    try {
        .....
        // 获得AppBindRecord,表示service对应的组件绑定在callerApp所描述的应用进程中
        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
        
        // 用来描述activity对应的Activity组件通过connection绑定到b(AppBindRecord)所对应的应用进程中的Service组件
        ConnectionRecord c = new ConnectionRecord(b, activity,
                connection, flags, clientLabel, clientIntent);
        
        IBinder binder = connection.asBinder();
        // 因为该Service组件可能被同一应用中的多个Activity组件使用同一个connection来绑定
        // 因此该Binder可能对应多个ConnectionRecord对象
        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 (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();
            // bringUpServiceLocked启动Service组件
            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
                return 0;
            }
        }
        ......
    } finally {
    }

    return 1;
}

先来看一个函数:retrieveAppBindingLocked:

public AppBindRecord retrieveAppBindingLocked(Intent intent,
        ProcessRecord app) {
    Intent.FilterComparison filter = new Intent.FilterComparison(intent);
    IntentBindRecord i = bindings.get(filter);
    if (i == null) {
        i = new IntentBindRecord(this, filter);
        bindings.put(filter, i);
    }
    // 将ProcessRecord与Service组件建立起关联
    AppBindRecord a = i.apps.get(app);
    if (a != null) {
        return a;
    }
    a = new AppBindRecord(this, i, app);
    i.apps.put(app, a);
    return a;
}

Service组件的启动机制深入学习》一文中的分析知,接下来调用bringUpServiceLocked方法来启动Service组件,接着调用realStartServiceLocked在app所描述的进程中启动该Activity组件:


注意realStartServiceLocked中有一步:

8、ActiveServices#realStartServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private final void realStartServiceLocked(ServiceRecord r,
                                          ProcessRecord app, boolean execInFg) throws RemoteException {
    ......
    try {
        ....
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        ....
    } catch (DeadObjectException e) {
    } finally {
    }

    ....
    // 这里执行进行绑定操作
    requestServiceBindingsLocked(r, execInFg);
    ....
}
可以看到通过scheduleCreateService启动Service组件之后,调用requestServiceBindingsLocked来执行绑定操作,由前面知启动方式的execInfg为false,即不需要绑定;

下面通过 scheduleCreateService启动Service组件的流程和Service组件的启动机制深入学习》中分析的启动流程相同;接下来分析Service组件启动之后,执行的绑定操作:


9、ActiveServices#requestBindingsLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
    // 由前面知,r.bindings中保存了一系列Service组件和app之间的绑定关系
    for (int i=r.bindings.size()-1; i>=0; i--) {
        // 执行遍历,将Service绑定到这些ProcessRecord中
        IntentBindRecord ibr = r.bindings.valueAt(i);
        if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
            break;
        }
    }
}

10、 ActiveServices#requestBindingsLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ServiceRecord.java**/
private final boolean requestServiceBindingLocked(ServiceRecord r,
                                                  IntentBindRecord i, boolean execInFg, boolean rebind) {
    if (r.app == null || r.app.thread == null) {
        // If service is not currently running, can't yet bind.
        return false;
    }
    // rebind参数用以标示是否需要重新绑定
    if ((!i.requested || rebind) && i.apps.size() > 0) {
        try {
            bumpServiceExecutingLocked(r, execInFg, "bind");
            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            // 接下来调用scheduleBindService去绑定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 (RemoteException e) {
            if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
            return false;
        }
    }
    return true;
}
代码逻辑较为简单,需要重新绑定或者i.apps中仍然有为执行完的绑定任务,都继续调用scheduleBindService来执行绑定任务;


r.app.thread的实际运行时类型为ApplicationThreadProxy。

11、 ApplicationThreadProxy#scheduleBindService:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
class ApplicationThreadProxy implements IApplicationThread {
    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind,
                                          int processState) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        intent.writeToParcel(data, 0);
        data.writeInt(rebind ? 1 : 0);
        data.writeInt(processState);
        mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
}
发送一个 SCHEDULE_BIND_SERVICE_TRANSACTION类型的IPC请求;


12、ApplicationThreadNative#onTransact:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/
public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
            case SCHEDULE_BIND_SERVICE_TRANSACTION: {
                data.enforceInterface(IApplicationThread.descriptor);
                IBinder token = data.readStrongBinder();
                Intent intent = Intent.CREATOR.createFromParcel(data);
                boolean rebind = data.readInt() != 0;
                int processState = data.readInt();
                scheduleBindService(token, intent, rebind, processState);
                return true;
            }
        }
    }

}
可以看到接下里调用子类ApplicationThread的scheduleBindService;


13:ApplicationThread#scheduleBindService:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative {
    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);
    }
}
类似得,通过H发送一个BIND_SERVICE请求,直接来看响应函数;


14、H:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/
private class H extends Handler {
    public static final int BIND_SERVICE            = 121;

    void handleMessage(Message msg) {
        switch (msg.what) {
            case BIND_SERVICE:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                handleBindService((BindServiceData)msg.obj);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
        }
    }

    private void handleBindService(BindServiceData data) {
        // data.token指向了一个ServiceRecord
        // 由启动过程知,mServices保存了所有启动后的Service,这里通过data.token关键字进行获取
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                try {
                    if (!data.rebind) {
                        // 可以看到这里就是自定义Service时重写的onBind函数
                        IBinder binder = s.onBind(data.intent);
                        // 继续通过publishService来实现
                        ActivityManagerNative.getDefault().publishService(
                                data.token, data.intent, binder);
                    } else { // 调用rebind情况
                        s.onRebind(data.intent);
                        ActivityManagerNative.getDefault().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                    ensureJitEnabled();
                } catch (RemoteException ex) {
                }
            } catch (Exception e) {
                .......
            }
        }
    }
}
可以看到系统先根据 data.token为关键字,获取相应的Service,然后调用onBind,这里的onBind即是在自定义Service中重写的onBind方法,获取该方法中返回的Binder对象。

然后继续调用ActivityManagerNative.getDefault().publishService来处理;

由前面易知ActivityManagerNative.getDefault()的实际类型为ActivityManagerProxy:


15、ActivityManagerProxy#publishService:

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager {
    public void publishService(IBinder token,
                               Intent intent, IBinder service) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        intent.writeToParcel(data, 0);
        data.writeStrongBinder(service);
        mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

}
发送一个 PUBLISH_SERVICE_TRANSACTION类型的IPC请求给AMS;

中间跳转过程省略,AMS处理PUBLISH_SERVICE_TRANSACTION类型请求的方法为:ActivityManagerService.publishService


16、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);
    }
}
这里会首先判断传入的参数是否为ServiceRecord,如果不是,则直接报错;

然后交托给ActiveServices的publishServiceLocked去处理;


17、ActiveServices#publishServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/
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对象
            IntentBindRecord b = r.bindings.get(filter);
            if (b != null && !b.received) {
                b.binder = service;
                b.requested = true;
                b.received = true; // 用来表示Services组件是否已经传递给AMS了,如果否则进入此处理函数中
                for (int conni=r.connections.size()-1; conni>=0; conni--) {
                    // 获取ConnectionRecord
                    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.conn是InnerConnection对象,调用其connected函数来进行连接
                            c.conn.connected(r.name, service);
                        } catch (Exception e) {
                        }
                    }
                }
            }

            serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
}
可以看到代码中主要的是获取到之前保存的  ConnectionRecord对象,然后调用其conn变量(InnerConnection对象,其实际类型为自定义的ServiceConnection封装成的ServiceDispatcher.ServiceConnection)的connected方法进行连接;

同时可以看到同一个ServiceConnection只会连接一次,因为ConnectionRecord对象的received变量会置为true,下一调用onBind时,并不会继续跳入到绑定逻辑代码中执行connect操作;


18、LoadedApk#ServiceDispatcher#InnerConnection#connected:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/
static final class ServiceDispatcher {
    private static class InnerConnection extends IServiceConnection.Stub {
        final WeakReference<ServiceDispatcher> mDispatcher;

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

        public void connected(ComponentName name, IBinder service) throws RemoteException {
            ServiceDispatcher sd = mDispatcher.get();
            if (sd != null) {
                sd.connected(name, service);
            }
        }
    }
}
最终又会去调用 ServiceDispatcher的connected函数;


19、LoadedApk#ServiceDispatcher#connected:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/
static final class ServiceDispatcher {
    public void connected(ComponentName name, IBinder service) {
        if (mActivityThread != null) {
            mActivityThread.post(new RunConnection(name, service, 0));
        } else {
            doConnected(name, service);
        }
    }
}
由前面知mActivityThread变量即为H,这里将一个RunConnection发送到主线程中去运行;


20、RunConnection:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/
static final class ServiceDispatcher {
    private final class RunConnection implements Runnable {
        RunConnection(ComponentName name, IBinder service, int command) {
            mName = name;
            mService = service;
            mCommand = command;
        }

        public void run() {
            // 根据命令的不同,执行绑定和取消绑定操作
            if (mCommand == 0) {
                doConnected(mName, mService);
            } else if (mCommand == 1) {
                doDeath(mName, mService);
            }
        }

        final ComponentName mName;
        final IBinder mService;
        final int mCommand;
    }
}
RunConnection是一个Runnable,其具体的执行逻辑在run中,根据命令Command的不同,执行绑定和取消绑定操作;由19步值,command为0,则执行doConnected;


21、ServiceDispatcher#doConnected: 

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/
static final class ServiceDispatcher {
    private final ServiceConnection mConnection;
    public void doConnected(ComponentName name, IBinder service) {
        .......
        // If there is a new service, it is now connected.
        if (service != null) {
            mConnection.onServiceConnected(name, service);
        }
    }

    public void doDeath(ComponentName name, IBinder service) {
        mConnection.onServiceDisconnected(name);
    }

}
ServiceDispatcher中保存了在代码中自定义的ServiceConnection,这里的绑定工作即是通过调用其onServiceConnected 来完成;


22、自定义的ServiceConnection:

// 定义ServiceConnection
private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        // 通过定义的Binder来获取Service实例来供使用
        mService = ((MyService.MyBinder) service).getService();
        Log.w(MyService.LOG_TAG, "Activity onServiceConnected");
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mService = null;
        // 当Service被意外销毁时
        Log.w(MyService.LOG_TAG, "Activity onServiceDisconnected");
    }
};
接下来就可以根据获取到的Service实例来直接对Service进行操作;


你可能感兴趣的:(Service绑定形式启动过程)