1.2 requestServiceBindingLocked
直接看ActiveServices的requestServiceBindingLocked方法,
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
•••
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
•••
} catch (TransactionTooLargeException e) {
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
throw e;
} catch (RemoteException e) {
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
return false;
}
}
return true;
}
和上面啟動服務時調用流程一樣,首先從AMS程序跨程序到要綁定的服務所在程序,然後發送消息到主線程,調用對應的函數,
在這裡調用handleBindService方法
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
}
} catch (Exception e) {
•••
}
}
}
該函數首先調用服務的onBind方法得到Binder,下一步自然是通過AMS将該對象傳回給發起綁定的程序。直接看AMS的publishService方法,
public void publishService(IBinder token, Intent intent, IBinder service) {
•••
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
publishServiceLocked方法如下,
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 b = r.bindings.get(filter);
if (b != null && !b.received) {
b.binder = service;
b.requested = true;
b.received = true;
for (int conni=r.connections.size()-1; conni>=0; conni--) {
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
•••
try {
c.conn.connected(r.name, service);
} catch (Exception e) {
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
直接調用c.conn.connected 方法,就像上一小節所論述的那樣,又一次跨程序調用到發起綁定的程序中。
1.3 bringUpServiceLocked
bringUpServiceLocked方法啟動服務的過程已經分析過了,這裡需要說明的是在realStartServiceLocked方法啟動線程過後,
會調用requestServiceBindingsLocked,最後仍然會調用requestServiceBindingLocked方法來綁定服務。
1.4小結
在onServiceConnected方法中, service參數,就是綁定的那個service的binder代理。現在已經打通了bindService()動作涉及
的三方關系:發起方、AMS、目标Service。具體的示意圖如下:
其實, bindService總體流程和startService類似,隻是多了一個綁定過程。也就是多了一個被綁定服務到AMS,然後到用戶端的回調過程。
并且,跨程序的互動過程和startService過程完全相同。