声明:图是借来的。
按时序图的顺序分析:
Activity
Activity是ContextWrapper的间接子类,在Activity中调用bindService其实是调用的ContextWrapper类中的bindService方法:
ContextWrapper:
Context mBase;
...
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
mBase是Context对象,在Context类中bindService是一个抽象方法,所以这里调用的是Context实现类即ContextImpl类的bindService方法:
ContextImpl.java:
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
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;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (mPackageInfo != null) {
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().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, 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中,mPackageInfo为LoadedApk的实例,在ContextImpl实例化的时候初始化,一般不为null,所以会执行sd = mPackageInfo.getServiceDispatcher:
LoadedApk.java
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, 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) {
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);
}
return sd.getIServiceConnection();
}
}
sd.getIServiceConnection返回的真实类型是ServiceDispatcher.InnerConnection。
LoadedApk.java:
ServiceDispatcher:
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
...
private static class InnerConnection extends IServiceConnection.Stub {
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);
}
}
}
IServiceConnection getIServiceConnection() {
return mIServiceConnection;
}
...
}
这里先记住,在ContextImpl中的bindServiceCommon方法中,sd得到的是ServiceDispatcher.InnerConnection类型的实例,这个实例中包含了传来的ServiceConnection。接下来回到ContextImpl中的bindServiceCommon中,看看接下来做了些什么:
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
ActivityManager.getService返回的就是AMS,所以这里调用的是AMS中的bindService,继续跟代码,发现调用的是ActiveServices中的requestServiceBIndingLocked方法:
ActivityManagerService.java:
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
...
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
ActiveServices.java:
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
...
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
...
return true;
}
到这里看到了比较眼熟的东西:r.app.thread.scheduleBindService,其实就是ActivityThread的scheduleBindService:
ActivityThread.java:
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
...
sendMessage(H.BIND_SERVICE, s);
}
通过handler,然后调用:
private void handleBindService(BindServiceData data) {
...
ActivityManager.getService().publishService(
data.token, data.intent, binder);
...
}
经过上面的分析,我们已经知道,这里其实就是调用的AMS中的publishService方法:
ActivityManagerService.java:
public void publishService(IBinder token, Intent intent, IBinder service) {
...
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
ActiveServices.java:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
...
c.conn.connected(r.name, service, false);
...
}
到最后,会从传来的参数中获取到conn对象,然后调用connected方法,这里就是回调的ServiceDispatcher.InnerConnection类的connected方法,然后调用ServiceDispatcher中的connected方法,进而回调从Activity中传入的ServiceConnection的回调方法如onServiceConnected等。
至此,bindservice流程分析完毕。