启动service之bindService
bindService就是将activity和service进行绑定,可以拿到service对象,也可以根据需要在合适的时机解绑service,让activity和service的生命周期有联系,下面分析一下bind的过程 step1:ContextImp#bindService
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
// 传入mMainThread.getHandler()
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
IServiceConnection sd;
// serviceconnection不可以为空
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (mPackageInfo != null) {
// step2 获取servicedispatcher对象
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
validateServiceIntent(service);
...
IBinder token = getActivityToken();
...
service.prepareToLeaveProcess(this);
// step3 调用到ams的bindservice
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
return res != 0;
}
step2 : 获取ServiceDispatcher mPackageInfo是LoadedApk类型
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
// mServices是loadedapk中的属性
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
if (map != null) {
sd = map.get(c);
}
if (sd == null) {
sd = new ServiceDispatcher(c, context, handler, flags);
if (map == null) {
map = new ArrayMap<>();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler);
}
// 返回的是IServiceConnection类型的binder对象
return sd.getIServiceConnection();
}
}
private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices = new ArrayMap<>();
上面的代码就是在本地查找是否有conn对应的ServiceDispatcher对象,如果没有的话就创建ServiceDispatcher,并创建conn和ServiceDispatcher的映射关系map,再以context为key,保存到mServices。 最后返回的是sd.getIServiceConnection()
IServiceConnection getIServiceConnection() {
//mIServiceConnection是的成员属性 在构造函数中赋值
return mIServiceConnection;
}
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
//mIServiceConnection 是InnerConnection类型
mIServiceConnection = new InnerConnection(this);
mConnection = conn;
mContext = context;
mActivityThread = activityThread;
}
// 实现了IServiceConnection.Stub的binder对象,
private static class InnerConnection extends IServiceConnection.Stub {
// 持有ServiceDispatcher的弱引用
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);
}
}
}
那么这里就获取到了ServiceDispatcher的binder对象。回到bindservice的step3,分析调用AMS的bindService