前言
本文基于Android10.0源码,从client端调用bindService()方法开始,一步步跟进源码,看看源码中是如何调用到service端代码,执行service生命周期方法,并回调client端ServiceConnection中onServiceConnected()回调方法的。示例代码请参考AIDL实现两app间通信。
代码分析
从client端调用bindService()方法开始,第一个参数传入Intent,第二个参数传入创建的ServiceConnection,其中包括两个回调函数。bindService()是在ContextWrapper类中实现的。
ContextWrapper.java
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
mBase是ContextImpl类型对象,调用ContextImpl的bindService()方法。
ContextImpl.java
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}
注意一下第5个参数,传入了主线程的handler,对应着client端的主线程handler,后面会用到它。
调用bindServiceCommon()方法。
ContextImpl.java
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
IServiceConnection sd;
...
//1
if (mPackageInfo != null) {
if (executor != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
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);
//2
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
if (res < 0) {
...
}
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
将这个方法分为两部分来看,一部分是注释1处创建sd对象,第二部是注释2处调用bindIsolatedService()方法与系统进程交互。先来看sd是如何被赋值的。在注释1处,这里mPackageInfo不为1,并且executor传入的为null,所以执行else分支调用mPackageInfo的getServiceDispatcher()方法得到一个sd对象,其中第一个参数conn为我们在客户端创建的ServiceConnection,第三个参数handler为前文提到的客户端app主线程的handler。mPackageInfo是LoadedApk类型对象。
LoadedApk.java
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
return getServiceDispatcherCommon(c, context, handler, null, flags);
}
调用getServiceDispatcherCommon()方法。
LoadedApk.java
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
Context context, Handler handler, Executor executor, 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) {
if (executor != null) {
sd = new ServiceDispatcher(c, context, executor, flags);
} else {
//1
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, executor);
}
return sd.getIServiceConnection();
}
}
executor为空,执行注释2所在的else分支,创建一个ServiceDispatcher实例。
LoadedApk.java
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
@UnsupportedAppUsage
private final ServiceConnection mConnection;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private final Context mContext;
private final Handler mActivityThread;
private final Executor mActivityExecutor;
private final ServiceConnectionLeaked mLocation;
private final int mFlags;
...
private static class InnerConnection extends IServiceConnection.Stub {
@UnsupportedAppUsage
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);
}
}
}
private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
= new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
//ServiceDispatcher构造方法
@UnsupportedAppUsage
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
//创建一个InnerConnection对象,是一个IBinder
mIServiceConnection = new InnerConnection(this);
mConnection = conn;
mContext = context;
mActivityThread = activityThread;
mActivityExecutor = null;
mLocation = new ServiceConnectionLeaked(null);
mLocation.fillInStackTrace();
mFlags = flags;
}
...
}
将客户端conn赋值给mConnection,主线程handler赋值给mActivityThread,并实例化了内部类InnerConnection赋值给mIServiceConnection,内部类InnerConnection继承了IServiceConnection.Stub,并实现了IServiceConnection中的connected()接口。接着看getServiceDispatcherCommon()方法,最后调用了sd.getIServiceConnection()方法。
LoadedApk.java
IServiceConnection getIServiceConnection() {
return mIServiceConnection;
}
返回了创建的InnerConnection对象。
回到bindServiceCommon()方法,接着会调用bindIsolatedService()方法,这个最终会调用到ActivityManagerService的bindIsolatedService方法。
ActivityManagerService.java
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
// Refuse possible leaked file descriptors
...
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}
}
首先做了一下参数检查,代码省略了,主要调用了bindServiceLocked()方法。mServices是ActiveServices类型对象。
ActiveServices.java
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException {
...
ServiceRecord s = res.record;
boolean permissionsReviewRequired = false;
...
try {
...
//1记录需要bind的service
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
//2
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage);
IBinder binder = connection.asBinder();
s.addConnection(binder, c);
b.connections.add(c);
...
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
//调用bringUpServiceLocked()方法
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
...
if (s.app != null && b.intent.received) {
// Service is already running, so we can immediately
// publish the connection.
try {
c.conn.connected(s.name, b.intent.binder, false);
} catch (Exception 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()方法
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
在注释2处创建ConnectionRecord对象,传入IServiceConnection对象。
ConnectionRecord.java
final class ConnectionRecord {
ConnectionRecord(AppBindRecord _binding,
ActivityServiceConnectionsHolder<ConnectionRecord> _activity,
IServiceConnection _conn, int _flags,
int _clientLabel, PendingIntent _clientIntent,
int _clientUid, String _clientProcessName, String _clientPackageName) {
binding = _binding;
activity = _activity;
conn = _conn;
flags = _flags;
clientLabel = _clientLabel;
clientIntent = _clientIntent;
clientUid = _clientUid;
clientProcessName = _clientProcessName;
clientPackageName = _clientPackageName;
}
}
将前面的IServiceConnection也就是InnerConnection赋值给conn。
接着通过asBinder得到IBinder对象,然后调用ServiceRecord的addConnection()方法。
ServiceRecord.java
private final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
= new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
void addConnection(IBinder binder, ConnectionRecord c) {
ArrayList<ConnectionRecord> clist = connections.get(binder);
if (clist == null) {
clist = new ArrayList<>();
connections.put(binder, clist);
}
clist.add(c);
// if we have a process attached, add bound client uid of this connection to it
if (app != null) {
app.addBoundClientUid(c.clientUid);
}
}
connections是一个ArrayMap,其key保存了IBinder,value保存了一个由ConnectionRecord对象组成的ArrayList,也就是clist。每一个ServiceConnection,都会有一个对应的InnerConnection(IBinder)。每一次bindService都会创建一个ConnectionRecord,里面保存了InnerConnection。对同一个ServiceConnection调用多次bindService,会得到多个ConnectionRecord,并且这些ConnectionRecord会保存在clist中,但是只有一个InnerConnection(IBinder)。
回到bindServiceLocked()方法,在try中,会调用bringUpServiceLocked()方法。
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
...
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
...
return null;
}
判断app是否为空,如果service所在的app还没有启动,所在的进程也就为空,需要先创建service所属app所在的进程,这个流程和activity启动是一样的,会通过Zygote进程fork出新app的进程,然后反射调用ActivityThread的attach()方法,接着会在attach()方法中调用ActivityManagerService的attachApplication()方法,然后调用attachApplicationLocked()方法。这一部分就不一步一步看了,可以参考Activity启动流程。直接看ActivityManagerService的attachApplicationLocked()方法。
ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//启动Activity调用了该方法
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
...
}
}
// Find any services that should be running in this process...
if (!badApp) {
try {
//启动service时会调用这个方法
didSomething |= mServices.attachApplicationLocked(app, processName);
checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
...
return true;
}
这里是与启动Activity有区别的地方,启动service会调用mServices的attachApplicationLocked()方法,mServices是ActiveServices类型对象。
ActiveServices.java
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mPendingServices.remove(i);
i--;
proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
mAm.mProcessStats);
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
if (!isServiceNeededLocked(sr, false, false)) {
// We were waiting for this service to start, but it is actually no
// longer needed. This could happen because bringDownServiceIfNeeded
// won't bring down a service that is pending... so now the pending
// is done, so let's drop it.
bringDownServiceLocked(sr);
}
}
} catch (RemoteException e) {
...
}
}
...
return didSomething;
}
调用realStartServiceLocked()方法。
ActiveServices.java
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
...
boolean created = false;
...
if (r.whitelistManager) {
app.whitelistManager = true;
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
if (newService && created) {
app.addBoundClientUidsOfNewService(r);
}
// If the service is in the started state, and there are no
// pending arguments, then fake up one so its onStartCommand() will
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null, 0));
}
sendServiceArgsLocked(r, execInFg, true);
...
}
首先会调用app.thread.scheduleCreateService()方法。这个方法最后会执行service的OnCreate生命周期函数。先往下看,一会再回来看这里。接着会调用requestServiceBindingsLocked()方法。
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
因为是发起的bindservice请求,前面提到的bindServiceLockedbindServiceLocked()方法中会通过s.retrieveAppBindingLocked()方法记录r.bindings数组,所以这里的r.bindings不为空,执行requestServiceBindingLocked()方法。
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
if (r.app == null || r.app.thread == null) {
// If service is not currently running, can't yet bind.
return false;
}
if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested
+ " rebind=" + rebind);
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.getReportedProcState());
if (!rebind) {
i.requested = true;
}
i.hasBound = true;
i.doRebind = false;
} catch (TransactionTooLargeException e) {
...
} catch (RemoteException e) {
...
}
}
return true;
}
首先判断service所在app和所在进程是否为空,如果为空的话,直接返回,无法进行bind。接着会在try中调用r.app.thread.scheduleBindService()方法。和前面的scheduleCreateService一起看一下。r.app.thread返回的是一个IApplicationThread对象,ApplicationThread是ActivityThread的内部类,它继承自IApplicationThread.Stub,这里用到了aidl,系统进程通过IApplicationThread与app进程通信,这个在Activity启动流程中也提到了,我们先看一下ApplicationThread的scheduleCreateService()方法,它是先于scheduleBindService()方法调用的。
ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
...
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
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);
}
...
}
从系统进程切换到了app进程,调用了scheduleCreateService()方法。H类上篇文章也说过,这是一个Hander。
class H extends Handler {
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
...
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
先执行CREATE_SERVICE这个case,调用handleCreateService()方法。
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//反射调用构造方法创建我们service的实例
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//调用service的attach方法
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用service的onCreate方法
service.onCreate();
mServices.put(data.token, service);
...
} catch (Exception e) {
...
}
}
首先通过调用instantiateService()方法返回一个service的实例,接着会调用这个service的onCreate方法。先看一下instantiateService()方法是如何返回一个service实例的,packageInfo是一个LoadedApk对象。
LoadedApk.java
private AppComponentFactory mAppComponentFactory;
public AppComponentFactory getAppFactory() {
return mAppComponentFactory;
}
返回一个AppComponentFactory对象,调用AppComponentFactory类的instantiateService()方法。
AppComponentFactory.java
public @NonNull Service instantiateService(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Service) cl.loadClass(className).newInstance();
}
可以看到,最终会通过反射创建一个Service实例,这里的className是我们自己服务端的service,所以就是创建了我们的service实例并返回。接着回到ActivityThread.java方法,会通调用已经创建service的onCreate()生命周期方法。最终会将这个service添加到mServices map中。
回到handler中,接着会执行BIND_SERVICE这个case,调用handleBindService()方法。
ActivityThread.java
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (DEBUG_SERVICE)
Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
}
}
}
}
通过mServices,找到已经创建的service。首先调用service的onBind()方法返回一个IBinder对象,也就是我们创建的那个IBinder。到这里,从一开始调用bindService方法,会在服务端service调用onCreate和onBind两个service生命周期方法的流程就梳理完了,还剩最后一步客户端的onServiceConnected()方法什么时候回调。接着看代码,在得到IBinder后,会调用
ActivityManager.getService()的publishService方法,调用ActivityManagerService的publishService()方法。
ActivityManagerService.java
final ActiveServices mServices;
public void publishService(IBinder token, Intent intent, IBinder service) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
调用ActiveServices的publishServiceLocked()方法。
ActiveServices.java
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
final long origId = Binder.clearCallingIdentity();
try {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
+ " " + intent + ": " + service);
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;
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
...
try {
c.conn.connected(r.name, service, false);
} catch (Exception e) {
...
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
重点在try中执行了c.conn.connected()方法。这个其实就是把上面讲的保存ConnectionRecord那个流程反过来,通过for循环取出ConnectionRecord的过程。得到ConnectionRecord,其中conn保存的是InnerConnection,这是在创建ConnectionRecord对象时传入的,这里如果不是很明白是怎么得到InnerConnection对象的话,可以往前看看,最终是调用了InnerConnection的connected()方法。
LoadedApk.java
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
其中sd为前面创建的ServiceDispatch对象,调用connected()方法。
LoadedApk.java
public void connected(ComponentName name, IBinder service, boolean dead) {
//executor为空
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
//mActivityThread不为空
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
mActivityThread为前面传入的客户端app主线程handler,所以不为空,调用主线程handler的post()方法,其中RunConnection为一个Runnable,会执行其中的run()方法。
private final class RunConnection implements Runnable {
RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
mName = name;
mService = service;
mCommand = command;
mDead = dead;
}
public void run() {
if (mCommand == 0) {
doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
final ComponentName mName;
final IBinder mService;
final int mCommand;
final boolean mDead;
}
执行run()方法,调用doConnected()方法。
public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
...
// If there is a new viable service, it is now connected.
if (service != null) {
mConnection.onServiceConnected(name, service);
} else {
...
}
}
mConnection为一开始传入的客户端创建的ServiceConnection对象,调用onServiceConnected()方法,也就回调了客户端的onServiceConnected()方法,其中service就是服务端onBinder()方法返回的IBinder对象。
到这里,从客户端发起bindService请求,到服务端Service执行onCreate()、onBinder()返回IBinder对象生命周期方法,并通过onBinder()返回一个IBinder对象,到带着这个IBinder对象回调到客户端ServiceConnection的onServiceConnected()方法整个流程就梳理完了,如有错误欢迎指出。