一、前言
我们知道Service一般有两种工作状态,一种是启动状态,一种是绑定状态。
启动状态的Service是这样生成的:
Intent intent = new Intent(this, MyService.class);
startService(intent);
绑定状态的Service是这样生成的:
Intent intent = new Intent(this, MyService.class);
bindService(intent, mServiceConnection, BIND_ATUO_CREATE);
针对这两种Service,我们从源码的角度分析一下两种工作状态的区别。
以下源码分析是基于Android SDK 27
二、启动状态的Service
从启动状态的Service的生成代码中可以知道,入口是ContextImpl的startService方法,如下所示。
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
startService方法调用了startServiceCommon方法,如下所示。
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
//调用了AMS的startService方法
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
} else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException(
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
startServiceCommon方法又通过ActivityManager.getService()对象调用了startService方法。而ActivityManager.getService()对象就是ActivityManagerService服务(AMS)。我们转到ActivityManagerService的startService方法,如下所示。
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
在上面的代码中,AMS通过了mServices这个对象,调用了mServices的startServiceLocked方法,而mServices是ActiveServices类型,它的startServiceLocked方法如下所示。
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
final boolean callerFg;
if (caller != null) {
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException();
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
...省略
ServiceRecord r = res.record;
if (!r.startRequested && !fgRequired) {
final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion, callingPid, false, false);
...省略
}
NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
callingUid, r.packageName, service, service.getFlags(), null, r.userId);
if (mAm.mPermissionReviewRequired) {
if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,
callingUid, service, callerFg, userId)) {
return null;
}
}
if (unscheduleServiceRestartLocked(r, callingUid, false)) {
...省略
}
...省略
if (!callerFg && !fgRequired && r.app == null
&& mAm.mUserController.hasStartedUserState(r.userId)) {
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
...省略
addToStarting = true;
} else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
addToStarting = true;
} else if (DEBUG_DELAYED_STARTS) {
...省略
}
} else if (DEBUG_DELAYED_STARTS) {
...省略
}
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
为了能关注重点代码,我们将部分代码逻辑省略掉了。最终ActiveServices的startServiceLocked方法调用了startServiceInnerLocked方法,如下所示。
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
...省略
return r.name;
}
startServiceInnerLocked方法继续调用了ActiveServices的内部方法——bringUpServiceLocked,而bringUpServiceLocked方法又继续调用了realStartServiceLocked方法。如下所示。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...省略
boolean created = false;
try {
...省略
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app);
throw e;
} finally {
...省略
}
if (r.whitelistManager) {
app.whitelistManager = true;
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
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。而app.thread对象是ActivityThread类型的。所以,创建Service就转化到了ActivityThread的scheduleCreateService方法,如下所示。
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);
}
scheduleCreateService方法中,通过sendMessage方法,发送了一个通知,其处理者是ActivityThread的内部类H,H继承了Handler,其中的handleMessage方法处理了上面的通知。在handleMessage方法中,对于H.CREATE_SERVICE的处理,如下所示。
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;
上面的逻辑中,调用了handleCreateService方法,如下所示。
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//1、使用反射的形式创建了Service对象
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
}
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//2、如果Application对象没有创建,则创建一个Application对象。在其中调用了Application的生命周期方法
Application app = packageInfo.makeApplication(false, mInstrumentation);
//3、调用Service对象的attach方法
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//4、调用Service对象的onCreate方法
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
上面的代码中,主要执行了以下几个步骤。
1、使用了反射的形式创建了Service对象。
2、如果Application对象没有创建,则创建Application对象,并调用其中的生命周期函数。
3、调用Service对象的attach生命周期方法。
4、调用Service对象的onCreate生命周期方法。
至此,启动状态的Service已经创建并运行起来了。而它的销毁过程其实和创建过程的流程差不多,最终都是在ActivityThread中执行相关的逻辑。这里就不再详细分析。我们接下来说一下绑定状态下的Service的工作过程。
三、绑定状态的Service
从绑定状态的Service的生成代码中可以知道,入口是ContextImpl的bindService方法,如下所示。
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}
ContextImpl中的bindService方法调用了bindServiceCommon方法,如下所示。
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) {
//1、传入ServiceConnection对象获取一个IServiceConnection对象
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、调用了AMS的bindService方法
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();
}
}
上面的代码中,调用了ActivityManager.getService()对象的bindService方法。前面我们分析启动状态的Service时,就知道了ActivityManager.getService()对象是一个ActivityManagerService(AMS)对象,所以我们转到了ActivityManagerService的bindService方法,如下所示。
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
ActivityManagerService的bindService方法中,使用了mServices的bindServiceLocked方法。而mServices对象是ActiveServices类型的。所以ActiveServices的bindServiceLocked方法如下所示。
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {
...省略
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
...省略
//记住ServiceRecord这个对象,特别重要
ServiceRecord s = res.record;
boolean permissionsReviewRequired = false;
// If permissions need a review before any of the app components can run,
// we schedule binding to the service but do not start its process, then
// we launch a review activity to which is passed a callback to invoke
// when done to start the bound service's process to completing the binding.
if (mAm.mPermissionReviewRequired) {
if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
s.packageName, s.userId)) {
permissionsReviewRequired = true;
final ServiceRecord serviceRecord = s;
final Intent serviceIntent = service;
RemoteCallback callback = new RemoteCallback(
new RemoteCallback.OnResultListener() {
@Override
public void onResult(Bundle result) {
synchronized(mAm) {
final long identity = Binder.clearCallingIdentity();
try {
if (!mAm.getPackageManagerInternalLocked()
.isPermissionsReviewRequired(
serviceRecord.packageName,
serviceRecord.userId)) {
try {
//这里的serviceRecord对象就是上面的s
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(),
callerFg, false, false);
} catch (RemoteException e) {
/* ignore - local call */
}
} else {
unbindServiceLocked(connection);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
});
mAm.mHandler.post(new Runnable() {
@Override
public void run() {
mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
}
});
}
}
final long origId = Binder.clearCallingIdentity();
try {
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (!s.hasAutoCreateConnections()) {
// This is the first binding, let the tracker know.
ServiceState stracker = s.getTracker();
if (stracker != null) {
stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
s.lastActivity);
}
}
}
mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState,
s.appInfo.uid, s.name, s.processName);
// Once the apps have become associated, if one of them is caller is ephemeral
// the target app should now be able to see the calling app
mAm.grantEphemeralAccessLocked(callerApp.userId, service,
s.appInfo.uid, UserHandle.getAppId(callerApp.uid));
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
//记住这个ConnectionRecord对象,后面绑定Service对象时会出现该对象
//这个ConnectionRecord对象存储了connection对象,即IServiceConnection对象。
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
//这里的connection是ServiceDispatcher的内部类InnerConnection,而InnerConnection继承了IServiceConnection.Stub
IBinder binder = connection.asBinder();
//s是ServiceRecord类型的对象,不要忘记了。
//s.connections是一个ArrayMap对象,它存储了一个ArrayList,这里的ArrayList是clist。
//而clist又存储了ConnectionRecord对象。而ConnectionRecord对象又存储了connection参数。
//而connection参数是一个IServiceConnection对象,也就是上面说过的InnerConnection对象。
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 ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
s.whitelistManager = 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);
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
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) {
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);
}
getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
在ActiveServices的bindServiceLocked方法中,又调用了ActiveServices的内部方法——bringUpServiceLocked,而bringUpServiceLocked又调用了realStartServiceLocked方法,如下所示。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...省略
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.services.add(r);
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
mAm.updateOomAdjLocked();
boolean created = false;
try {
if (LOG_SERVICE_START_STOP) {
String nameTerm;
int lastPeriod = r.shortName.lastIndexOf('.');
nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
EventLogTags.writeAmCreateService(
r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
}
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app);
throw e;
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
// Cleanup.
if (newService) {
app.services.remove(r);
r.app = null;
}
// Retry.
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
if (r.whitelistManager) {
app.whitelistManager = true;
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
// 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);
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (from start): " + r);
stopServiceLocked(r);
}
}
}
上面的代码中,通过app.thread对象的scheduleCreateService方法创建了Service对象。我们已经知道app.thread是ActivityThread对象,所以这里是调用了ActivityThread的scheduleCreateService方法,如下所示。
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);
}
这个scheduleCreateService方法和上面我们分析的启动状态的Service的创建方法是一样的,最后都是通过反射的形式创建了Service对象,并调用了Service对象的attach、onCreate等生命周期方法。
如果仅到此为止,启动状态的Service和绑定状态的Service就没什么区别了。但是既然官方给定了两种不同状态的Service,它们之间肯定存在着区别的。
我们回溯到之前已经分析过的代码,终于在ActiveServices的realStartServiceLocked方法中看到,它在执行了app.thread.scheduleCreateService创建Service对象后,接着执行了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;
}
}
}
Note:启动状态的Service也会调用requestServiceBindingsLocked这个方法,但是其中的r.bindings.size为空,因此不能往下执行逻辑。
对于绑定状态的Service来说,ActiveServices的requestServiceBindingsLocked方法中又执行了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);
//绑定Service对象
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
if (!rebind) {
i.requested = true;
}
i.hasBound = true;
i.doRebind = false;
} catch (TransactionTooLargeException e) {
} catch (RemoteException e) {
}
}
return true;
}
上面的代码中调用了r.app.thread的scheduleBindService方法,而r.app.thread是一个ActivityThread对象,其中的scheduleBindService方法如下所示。
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;
sendMessage(H.BIND_SERVICE, s);
}
scheduleBindService方法通过调用sendMessage方法,发送了一个消息给ActivityThread的内部类H处理,其处理逻辑如下所示。
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
在内部类H的handleMessage方法中,对于H.BIND_SERVICE的处理是调用了handleBindService方法,如下所示。
private void handleBindService(BindServiceData data) {
//从mServices获取上面创建的Service对象
Service s = mServices.get(data.token);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) { //第一次绑定时的逻辑
//执行Service对象的onBind方法,onBind方法返回一个IBinder对象
IBinder binder = s.onBind(data.intent);
//将onBind方法返回的IBinder对象作为参数,调用AMS的publishService方法
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} catch (Exception e) {
}
}
}
handleBindService方法主要做了以下几件事:
1、从mServices这个变量中获取一个Service对象,该Service对象就是我们上面创建过的。
2、调用Service对象的onBind方法,该方法返回了一个IBinder对象。该IBinder对象可以简单理解为是Service的逻辑处理。
3、调用了ActivityManagerService(AMS)的publishService方法,将该IBinder对象作为参数传递进去。
我们接着看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);
}
}
上面的代码中调用了ActiveServices的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;
//ServiceRecord的connections是一个ArrayMap对象。
//遍历该ArrayMap对象的Value值,Value值是一个ArrayList对象
//遍历ArrayList对象,获取每一个ConnectionRecord对象,通过filter找到
//相应的ConnectionRecord对象
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);
if (!filter.equals(c.binding.intent.intent)) {
continue;
}
try {
//c是ConnectionRecord对象,其中的conn是InnerConnection
//对象,这里实际上是调用了InnerConnection的connected方法。
c.conn.connected(r.name, service, false);
} catch (Exception e) {
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
上面的注释提到,在try方法块中调用了c.conn对象的connected方法,而c.conn对象是InnerConnection对象。所以我们转到InnerConnection对象的connected方法,如下所示。
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
上面的代码首先通过mDispatcher对象获取了LoadedApk的内部类ServiceDispatcher对象,然后调用了该对象的connected方法。如下所示。
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
上面的connected方法中有两个分支,而不论哪个分支,最终都会执行到doConnected方法,所以我们直接看doConnected方法的逻辑,如下所示。
public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
synchronized (this) {
old = mActiveConnections.get(name);
//Service已经绑定过了
if (old != null && old.binder == service) {
// Huh, already have this one. Oh well!
return;
}
//将新的Service信息存储起来
if (service != null) {
info = new ConnectionInfo();
info.binder = service;
info.deathMonitor = new DeathMonitor(name, service);
try {
service.linkToDeath(info.deathMonitor, 0);
mActiveConnections.put(name, info);
} catch (RemoteException e) {
mActiveConnections.remove(name);
return;
}
} else {
mActiveConnections.remove(name);
}
if (old != null) {
old.binder.unlinkToDeath(old.deathMonitor, 0);
}
}
///将旧的Service进行解绑的操作
if (old != null) {
mConnection.onServiceDisconnected(name);
}
if (dead) {
mConnection.onBindingDied(name);
}
//调用mConnection对象的onServiceConnected方法绑定新的Service
//这里的mConnection就是ServiceConnection对象,也即是我们最开始调用bindService方法时
//传进来的参数。这里的service参数就是Service服务的onBind方法返回的IBinder对象。
if (service != null) {
mConnection.onServiceConnected(name, service);
}
}
上面的代码中,如果是第一次连接,会走到最后的mConnection的onServiceConnected方法。这里的mConnection对象就是ServiceConnection对象,也就是我们最开始调用bindService传进来的参数。
这里看一个调用bindService方法的小例子:
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
bookManager = IBookManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
bookManager = null;
}
}, BIND_AUTO_CREATE);
可以看到ServiceConnection的onServiceConnected方法,传进来的第二个参数service是IBinder对象,也就是我们上面分析的Service的onBind方法返回的IBinder对象。通过该IBinder对象,我们可以实现Activity和Service(本地Service或者远程Service)之间的交互。
至此,Service的两种状态的工作过程都分析完毕了。这里先抛出两个问题流到后续再讨论:
1、为什么使用bindService方法时,Activity和Service是绑定起来的,当Activity被销毁,Service也会跟着被销毁?
2、Activity和Service的交互,Service可以是本地的或者是跨进程的,两者之间有什么区别?
网友评论