bindService绑定服务源码流程
终于轮到双休,周末可以摸一下书。本次阅读的源码基于API 30,将来回头再看可能有误。
1、绑定Service
Service作为四大组件之一,承担着执行后台任务的重担。有两种启动方式:①startService,②bindService。
本篇跟随源码了解绑定Service的过程。绑定Service仅需简单几步:
//构造启动目标Service所需Intent
Intent intent = new Intent();
//构造绑定服务所需ServiceConnection连接对象
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
//绑定服务
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
将Service的绑定过程拆分开来看,并不复杂,逻辑清晰。
1.1、Context中处理
先从调用Context上下文的bindService(...)方法开始:
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}

关于Context详见另一篇:各种Context及其初始化流程。它的实现类是ContextImpl,实现了bindService(...)方法:
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}
内部调用bindServiceCommon(...)方法进入到AMS服务处理Service的启动和绑定。
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
...
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
...
}
在进入AMS之前,先留意一下在bindServiceCommon(...)方法中获取了LoadedApk.ServiceDispatcher实例,封装了绑定服务所创建的ServiceConnection接口对象,这在后面绑定服务后回调用到。
1.2、AMS服务处理
现在对AMS已经不再陌生,应用侧通过AIDL接口与系统服务完成远程调用。
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
...
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}
调用ActiveServices中的bindServiceLocked()方法完成服务的绑定,这个方法很长很复杂。简化看:

1.3、创建服务*
这一步不一定必须执行。如果服务没有创建还会先创建Service。以bringUpServiceLocked()方法为例开始,再执行realStartServiceLocked()方法,进入ApplicationThread执行scheduleCreateService(),向Handler发送CREATE_SERVICE消息执行handleCreateService()创建Service。
1.4、绑定服务
通过requestServiceBindingsLocked()完成服务的绑定,通样进入ApplicationThread执行scheduleBindService(),向Handler发送BIND_SERVICE消息执行handleBindService()绑定Service。
2、bindService生命周期及回调
通过对Service绑定源码流程的分析,对绑定Service的回调及生命周期会有更深刻的理解。

2.1、onServiceConnected回调
接着1.4节继续往下看,执行handleBindService()方法
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
...
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
...
}
回到AMS服务,执行publishService()方法:
public void publishService(IBinder token, Intent intent, IBinder service) {
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
在ActiveServices的publishServiceLocked()方法中执行Service的连接:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
...
try {
c.conn.connected(r.name, service, false);
} catch (Exception e) {
}
...
}
还记得在1.1节中提到的LoadedApk.ServiceDispatcher吗?上面方法中回调的对象正是LoadedApk.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);
}
}
}
经过doConnected()层层调用,最终调用ServiceConnection的onServiceConnected()回调。
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);
}
}
2.2、onServiceDisconnected回调
同上,Service断开连接的时候在doDeath()方法中回调ServiceConnection的onServiceDisconnected()方法。
public void doDeath(ComponentName name, IBinder service) {
...
mConnection.onServiceDisconnected(name);
}
2.3、onBind回调
在2.1节中提到的handleBindService()方法也执行了Service的onBind()回调:
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
...
IBinder binder = s.onBind(data.intent);
...
}
Service的onCreate()回调,当然是在Service创建的时候调用。
private void handleCreateService(CreateServiceData data) {
...
Service service = null;
...
service.onCreate();
...
}
2.4、onUnBind回调
Service被“解绑”的时候,通过handleUnbindService()回调onUnBInd()方法。
private void handleUnbindService(BindServiceData data) {
Service s = mServices.get(data.token);
...
boolean doRebind = s.onUnbind(data.intent);
...
}