敞开生长之旅!这是我参与「日新计划 12 月更文挑战」的第27天,点击检查活动详情
Service有两种状况,一种是发动状况首要用于履行后台计算,另一种是绑定状况,首要用于其他组件与Service之间的交互,两种状况是能够共存的。
1.Service的发动进程
Service的发动进程要从startService看起
//ContextWrapper#startService
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
代码中的mBase的原型是Context的完结类ContextImpl,在Activity创立时会经过attach办法将一个ContextImpl目标相关起来,这个ContextImpl便是代码中的mBase,从ContextWrapper代码中能够看出里边的大多数操作都是经过mBase完结的,这是一种桥接模式, 持续看ContextImpl中的startService
//ContextImpl#startService
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
//ContextImpl#startServiceCommon
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
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();
}
}
在ContextImpl中的startService进入到startServiceCommon,然后倒了ActivityManager.getService().startService()
这儿先剖析一下ActivityManager.getService()
//ActivityManager#getService
@UnsupportedAppUsage
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
看到Binder就能够理解这儿是一个获取跨进程服务,获取的服务是ActivityManagerService(AMS),它承继自IActivityManager.Stub,是个Binder目标,经过单例提供服务。AMS运转在体系进程中(system_server),到这儿原本运转在客户端的startService就转移到了AMS中运转,看一下AMS中startService的完结
//ActivityManagerService#startService
@Override
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;
}
}
上面的代码中会经过mService目标来完结Service后续的发动进程,mService的类型是ActiveServices,它辅佐AMS办理Service,包含Service的发动、绑定、停止等,在ActiveServices的startServiceLocked的办法中又进入了startServiceInnerLocked()
//ActiveServices#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;
StatsLog.write(StatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid, r.name.getPackageName(),
r.name.getClassName(), StatsLog.SERVICE_STATE_CHANGED__STATE__START);
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT;
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
} else if (DEBUG_DELAYED_STARTS) {
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
}
if (first) {
smap.rescheduleDelayedStartsLocked();
}
} else if (callerFg || r.fgRequired) {
smap.ensureNotStartingBackgroundLocked(r);
}
return r.name;
}
在startServiceInnerLocked的参数中有一个ServiceRecord目标,ServiceRecord描绘的是一个Service记录,它贯穿整个Service的发动进程。在startServiceInnerLocked并没有完结Service的发动,而是交给了bringUpServiceLocked,在bringUpServiceLocked办法中又调用了realStartServiceLocked,由这个办法完结Service的发动
//AcyiveServices#realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
...
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
...
sendServiceArgsLocked(r, execInFg, true);
...
}
在realStartServiceLocked办法中首要经过app.thread.scheduleCreateService创立Service目标并调用它的onCreate办法,然后再经过sendServiceArgsLocked办法来调用Service的其他办法如startServiceCommand,这两个进程均是进程间的通讯。app.thread目标是IApplicationThread类型,它实际上是一个Binder,它的具体完结是ApplicationThread,因为ApplicationThread是ActivityThread的内部类因此进入ActivityThread中的ApplicatonThread中检查scheduleCreateService的完结
//ActivityThread#ApplicationThread#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中的完结与Activity的发动类似,都是经过把音讯发送到Handler的完结类H来完结的,终究交给handleCreateService来完结
//ActivityThread#handleCreateService
@UnsupportedAppUsage
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 = 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(context, this, data.info.name, data.token, app,
ActivityManager.getService());
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);
}
}
}
handleCreateService首要做了几件事:
-
- 经过类加载器创立Service实例
- 创立ContextImpl目标
- 创立Application目标并调用它的onCreate办法
- 经过Service的attach办法树立ContextImpl、Application与Service之间的联系
- 最后调用Service的onCreate办法并将Service目标存储到ActivityThread中的一个列表中,列表界说如下:
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
Service的onCreate办法履行了也就意味着Service现已发动了,除此之外ActivityThread中还会经过handleServiceArgs办法调用Service的onStartCommand办法。
//ActivityThread#onStartCommand
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
if (data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
}
int res;
if (!data.taskRemoved) {
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
}
}
}
}
2.Service的绑定进程
Service的绑定进程也是从ContextWrapper开始的
//ContextWrapper
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
mBase也是ContextImpl然后进入ContextImpl的bindService
//ContextImpl#bindService
@Override
public boolean bindService(
Intent service, int flags, Executor executor, ServiceConnection conn) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, null, executor, getUser());
}
//ContextImpl#bindServiceCommon
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;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (handler != null && executor != null) {
throw new IllegalArgumentException("Handler and Executor both supplied");
}
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);
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, 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首要做了两件工作,第一件工作便是把ServiceConnection目标转化为ServiceDispatcher.InnerConnection,那么为什么不直接运用ServiceConnection目标呢,这是因为服务的绑定有可能是跨进程的,因此ServiceConnection有必要借助Binder才能让长途服务端回调自己的办法,而ServiceDispatcher的内部类InnerConnection正好充当了这个角色,InnerConnection承继自IServiceConnection.Stub。进入办法getServiceDispatcher()剖析
//LoadApk#getServiceDispatcher
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Executor executor, int flags) {
return getServiceDispatcherCommon(c, context, null, executor, flags);
}
//LoadApk#getServiceDispatcherCommon
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 {
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();
}
}
在getServiceCommon办法中实例化了ServiceDispatcher,它的作用是连接ServiceConnection和InnerConnection。
上面代码中的mServices是一个ArrayMap,界说如下
private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
= new ArrayMap<>();
mService.put(context, map);//这儿的map界说如下
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
//LoadApk#ServiceDispatcher
ServiceDispatcher(ServiceConnection conn,
Context context, Executor activityExecutor, int flags) {
mIServiceConnection = new InnerConnection(this);
mConnection = conn;
mContext = context;
mActivityThread = null;
mActivityExecutor = activityExecutor;
mLocation = new ServiceConnectionLeaked(null);
mLocation.fillInStackTrace();
mFlags = flags;
}
这个mService存储的是一个应用当前活动的ServiceConnection和ServiceDispatcher的映射联系。体系会首要查找是否存在相同的ServiceConnection,如果不存在就重新创立一个新的ServiceDispatcher目标并将其存储在mService中,其映射联系的key是ServiceConnection,value是ServiceDispatcher。ServiceDispatcher目标的内部存储了ServiceConnection和InnerConnection,当Service和客户端树立连接后,体系会经过InnerConnection来调用ServiceConnection中的onServiceConnected办法,这个进程有可能是跨进程的。当ServiceDispatcher创立好了以后就会经过getServiceDispatcher会回来其保存的InnerConnection目标。
//这是调用onServiceConnected的办法调用联系
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 {
sd.connected(name, service, dead);
}
}
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
public void doConnected(ComponentName name, IBinder service, boolean dead) {
...
// If there is a new viable service, it is now connected.
if (service != null) {
mConnection.onServiceConnected(name, service);
} else {
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
}
}
当bindServiceCommon办法中的getServiceDispatcher回来后就要完结第二件工作,这儿进入ActivityManager.getService.bindIsoatedService()
@UnsupportedAppUsage
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
这儿回到了AMS中,那么检查AMS中的bindIsolatedService做了什么
//ActivityManagerService#bindIsolatedService
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
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
// Ensure that instanceName, which is caller provided, does not contain
// unusual characters.
if (instanceName != null) {
for (int i = 0; i < instanceName.length(); ++i) {
char c = instanceName.charAt(i);
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9') || c == '_' || c == '.')) {
throw new IllegalArgumentException("Illegal instanceName");
}
}
}
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}
}
这儿的mServices是ActiveServices,这儿进入了ActivityServices的bindServiceLocked办法中,在这个办法中又进入了requestServiceBindingLocked办法
//AcyiveServices#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) {
// Keep the executeNesting count accurate.
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
throw e;
} catch (RemoteException e) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
return false;
}
}
return true;
}
在requestServiceBindingLocked办法中经过app.thread调用了scheduleBindService办法,这儿app.thread是IApplicationThread,它的完结类是ApplicationThread,所以scheduleBindService进入到ActivityThread的内部类ApplicationThread中剖析
//ActivityThread#ApplicationThread#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;
if (DEBUG_SERVICE)
Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
+ Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
sendMessage(H.BIND_SERVICE, s);
}
能够看到这儿仍是经过sendMessage发送了音讯,这个H同样是Handler的完结类,这儿就直接进入处理BIND_SERVICE的办法handleBindService中剖析
//ActivityThread#handBindService
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);
}
}
}
}
在handleBindService办法中首要根据Service的token出Service的目标,然后调用onBind办法回来一个Bidner目标给客户端运用。理论受骗onBind办法被调用以后Service就处于绑定状况了,可是客户端并不知道,所以还要调用客户端的onServiceConnected办法,这个办法在ServiceConnection中,这个进程是由ActivityManager.getService().publishService完结的,getService这儿不再剖析直接进入publishService的办法剖析
//ActivityManagerService#publishService
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);
}
}
//ActivityServices#publishServiceLocked
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);
if (!filter.equals(c.binding.intent.intent)) {
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Not publishing to: " + c);
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Published intent: " + intent);
continue;
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
try {
c.conn.connected(r.name, service, false);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + r.shortInstanceName
+ " to connection " + c.conn.asBinder()
+ " (in " + c.binding.client.processName + ")", e);
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
publishServiceLocked办法中只需要关怀一行代码c.conn.connected(r.name,service,false);
这儿的c是ConnectionRecord,c.conn是ServiceDispatcher.InnerConnection,参数中的service便是onBind办法回来的Binder目标,这儿先看一下ServiceDispatcher.InnerConnection
//LoadApk#ServiceDispatcher#InnerConnection
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);
}
}
}
这儿的sd是ServiceDispatcher,sd.connected便是调用了ServiceDispatcher中的connected办法,然后在connected办法中进入了doConnected办法
//LoadApk#ServiceDispatcher#connected
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
//LoadApk#doConnected
public void doConnected(ComponentName name, IBinder service, boolean dead) {
...
// If there is a new viable service, it is now connected.
if (service != null) {
mConnection.onServiceConnected(name, service);
} else {
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
}
}
在doConnected办法中mConnection.onServiceConnected履行后Service的绑定进程也就剖析完了,还要说明一下mConnection,在ServiceDispatcher内部保存了客户端的serviceConnection目标因此也就能够很便利的调用onServiceConnected办法。