1. client进程
2. system_server进程,主要是在AMS和ActiveService里面处理
3. service进程
首先由client进程发起
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/content/ContextWrapper.java
activity或者service调用bindService()方法后进入ContextWrapper.java,然后再进入ContextImpl.java,最后在ContextImpl.java里面执行bindServiceCommon()方法
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
UserHandle user) {
IServiceConnection sd;
...
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
} else {
...
}
try {
...
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
...
return res != 0;
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
}
1) 首先创建LoadedApk.ServiceDispatcher.InnerConnection对象sd,该对象是专门用来与servcie链接的Binder对象.
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) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service);
}
}
}
IServiceConnection.Stub是IServiceConnection.aidl文件编译后自动生成的类,专门用于binder通信.
2) 然后调用ActivityManager的bindService()方法进入AMS执行.
重点参数: mMainThread.getApplicationThread() 是client进程的ApplicationThread对象,该对象是个binder,AMS用他来获取client进程的ProcessRecord.
sd 是InnerConnection对象,也是一个Binder,AMS通过他最终回调client进程的onServiceConnected()方法,并将service的binder代理对象传给client.
可以看到client只是发起绑定请求,并把参数传递给AMS.核心参数是client进程的ApplicationThread对象和InnerConnection对象.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:现在进入system_server进程.
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
frameworks/base/core/java/android/app/ApplicationThreadProxy.java(ApplicationThreadProxy类其实是在ApplicationThreadNative.java文件里面)
进入系统进程,通过AMS的bindService()方法进入ActiveServices.java的bindServiceLocked().
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags,
String callingPackage, int userId) throws TransactionTooLargeException {
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
ActivityRecord activity = null;
......
final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
//获取service的ServiceRecord
ServiceRecord s = res.record;
......
//创建AppBindRecord和ConnectionRecord
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
//将新的链接加到链接列表中
IBinder binder = connection.asBinder();
ArrayList<ConnectionRecord> clist = s.connections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
s.connections.put(binder, clist);
}
clist.add(c);
b.connections.add(c);
if (activity != null) {
if (activity.connections == null) {
activity.connections = new HashSet<ConnectionRecord>();
}
activity.connections.add(c);
}
b.client.connections.add(c);
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.hasAboveClient = true;
}
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
mServiceConnections.put(binder, clist);
}
clist.add(c);
//启动service
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
return 0;
}
}
//更新service所在进程的oomAdj和Lru,也就是优先级.
if (s.app != null) {
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
s.app.treatLikeActivity = true;
}
// This could have made the service more important.
mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
|| s.app.treatLikeActivity, b.client);
mAm.updateOomAdjLocked(s.app);
}
if (s.app != null && b.intent.received) {
// 若Service已经和client进程的其他组件绑定,那么AMS就持有他的binder,直接通过InnerConnection接口调用client的connected()方法,最终回调onServiceConnected()方法并将service的binder传给client,完成绑定.
try {
c.conn.connected(s.name, b.intent.binder);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + s.shortName
+ " to connection " + c.conn.asBinder()
+ " (in " + c.binding.client.processName + ")", e);
}
// If this is the first app connected back to this binding,
// and the service had previously asked to be told when
// rebound, then do so.
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
getServiceMap(s.userId).ensureNotStartingBackground(s);
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
在该方法里面主要做了这几件事:
1) 获取service的ServiceRecord
2) 创建AppBindRecord和ConnectionRecord
3) 将新的链接加到service的链接列表中
4) 启动service(如果需要的话)
5) 更新service所在进程的oomAdj和Lru,也就是进程优先级.
6) 判断Service是否已经和client进程的其他组件绑定.如果已经绑定,直接通过InnerConnection接口调用client的connected()方法,最终回调onServiceConnected()方法并将service的binder代理对象BinderProxy传给client,完成绑定.
如果client进程没有组件已经与service绑定,就调用requestServiceBindingLocked()方法
该方法通过执行
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,r.app.repProcState);
进入ApplicationThreadProxy.java执行
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind,
int processState) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
intent.writeToParcel(data, 0);
data.writeInt(rebind ? 1 : 0);
data.writeInt(processState);
mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
通过binder通信进入ApplicationThreadNative.java
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:现在进入service进程.
frameworks/base/core/java/android/app/ApplicationThreadNative.java
frameworks/base/core/java/android/app/ActivityThread.java
首先调用ApplicationThreadNative.java的onTransact()方法
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
.......
case SCHEDULE_BIND_SERVICE_TRANSACTION: {
data.enforceInterface(IApplicationThread.descriptor);
IBinder token = data.readStrongBinder();
Intent intent = Intent.CREATOR.createFromParcel(data);
boolean rebind = data.readInt() != 0;
int processState = data.readInt();
scheduleBindService(token, intent, rebind, processState);
return true;
}
}
然后进入ApplicationThread,他是ActivityThread.java的内部类,继承ApplicationThreadNative,运行在binder线程,专门用来接收AMS发过来的命令.
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
if (DEBUG_SERVICE)
Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
+ Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
sendMessage(H.BIND_SERVICE, s);
}
service进程主线程收到消息后对消息进行处理,调到ActivityThread的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); (1)
ActivityManagerNative.getDefault().publishService( (2)
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) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
}
}
}
}
(1)处调用service的onBind()方法获取service的Stub对象.Stub是binder通信的本地端.
(2)调用ActivityManager的publishService()方法进入AMS,并把service的Stub对象传过去.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:现在进入system_server进程.
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
通过AMS的publishService()方法进入ActiveService的publishServiceLocked()方法
该方法的核心语句:
try {
c.conn.connected(r.name, service);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + r.name +
" to connection " + c.conn.asBinder() +
" (in " + c.binding.client.processName + ")", e);
}
及调用client进程InnerConnection对象connected方法回到client进程,其中参数service是service的binder代理对象BinderProxy. 这个BinderProxy是service的Stub经过Binder机制转换而来.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
frameworks/base/core/java/android/app/LoadedApk.java
进入LoadedApk.ServiceDispatcher.InnerConnection的connected()方法
InnerConnection是ServiceDispatcher的内部类,ServiceDispatcher是LoadedApk的内部类.InnerConnection是一个binder,专门接收AMS的回调.
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) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service);
}
}
}
最后调到doConnected()方法,并在该方法中执行 mConnection.onServiceConnected(name, service);这条语句回调方法,并将service的binder代理对象BinderProxy传给client进程发起绑定动作的组件.
到此,应用组件绑定其他进程中service的调用流程结束,其本质是client进程通过AMS获取其他进程中service的binder代理对象BinderProxy对象.拿到该对象后就可以进行RPC调用.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
onServiceConnected()方法并把service的binder代理对象BinderProxy传给client进程.
2. AMS接收到绑定服务请求后,首先将链接加到service的连接列表中,判断是否需要启动service,判断是否已有client连接到目标service,如果已有连接,则直接回调onServiceConnected()方法并将service的binder传给client,完成绑定.如果
没有连接,就向service所在进程发起连接请求.
3. service收到连接请求后, 首先通过service的onBind()方法获取service的stub对象,也就是Binder对象,然后调用ActivityManager的publishService()回到AMS,并将service的stub对象传给AMS.
4. AMS在收到service的stub对象后,将其转换为Binder代理对象BinderProxy,并调用client进程的connect方法回到client进程,并将service的BinderProxy传给client进程.
5. client进程最终调用onServiceConnected()方法将service的BinderProxy对象传给发起绑定请求的应用组件.
绑定的本质就是client进程通过AMS去service进程获取service的BinderProxy.