
聲明:圖是借來的。
按時(shí)序圖的順序分析:
Activity
Activity是ContextWrapper的間接子類,在Activity中調(diào)用bindService其實(shí)是調(diào)用的ContextWrapper類中的bindService方法:
ContextWrapper:
Context mBase;
...
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
mBase是Context對(duì)象,在Context類中bindService是一個(gè)抽象方法,所以這里調(diào)用的是Context實(shí)現(xiàn)類即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為L(zhǎng)oadedApk的實(shí)例,在ContextImpl實(shí)例化的時(shí)候初始化,一般不為null,所以會(huì)執(zhí)行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返回的真實(shí)類型是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類型的實(shí)例,這個(gè)實(shí)例中包含了傳來的ServiceConnection。接下來回到ContextImpl中的bindServiceCommon中,看看接下來做了些什么:
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
ActivityManager.getService返回的就是AMS,所以這里調(diào)用的是AMS中的bindService,繼續(xù)跟代碼,發(fā)現(xiàn)調(diào)用的是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,其實(shí)就是ActivityThread的scheduleBindService:
ActivityThread.java:
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
...
sendMessage(H.BIND_SERVICE, s);
}
通過handler,然后調(diào)用:
private void handleBindService(BindServiceData data) {
...
ActivityManager.getService().publishService(
data.token, data.intent, binder);
...
}
經(jīng)過上面的分析,我們已經(jīng)知道,這里其實(shí)就是調(diào)用的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);
...
}
到最后,會(huì)從傳來的參數(shù)中獲取到conn對(duì)象,然后調(diào)用connected方法,這里就是回調(diào)的ServiceDispatcher.InnerConnection類的connected方法,然后調(diào)用ServiceDispatcher中的connected方法,進(jìn)而回調(diào)從Activity中傳入的ServiceConnection的回調(diào)方法如onServiceConnected等。
至此,bindservice流程分析完畢。