前言
本文基于Android 11,参考《Android进阶解密》一书资料。了解Service的启动和绑定流程,以及Service的Context创建过程。
由于基于分析流程,忽略很多细节分支。各位在看源码的时候,要尽可能忽略细节,分析整体流程之后,还有精力的话再去看细节。例如有些属性是在后面赋值的,如果在前面追究,难哦。
另:阅读这种流程需要很大的耐心和毅力。建议在心情愉悦想要学习的时候搭配源码一起食用。
一、Service 的启动流程
1、ContextImpl.startService
启动一个Service,通常在Activity调用startService来启动。
@OverridepublicComponentNamestartService(Intent service) {
returnstartServiceCommon(service, false, mUser);
}
复制代码
2、ContextImpl.startServiceCommon
startServiceCommon检查intent内容是否合法,然后做一些离开当前进程的准备操作。调用 ActivityManager.getService()获得AMS的本地引用,并调用其startService函数。也就是说通过Binder机制跨进程通信调用了AMS的startService函数。
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
//检查intent 的compant和package是否合法validateServiceIntent(service);
...
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
复制代码
通过 ActivityManager.getService()的实现。
@UnsupportedAppUsagepublicstatic IActivityManager getService() {
return IActivityManagerSingleton.get();
}
@UnsupportedAppUsageprivatestaticfinal Singleton<IActivityManager> IActivityManagerSingleton =
newSingleton<IActivityManager>() {
@Overrideprotected IActivityManager create() {
finalIBinderb= ServiceManager.getService(Context.ACTIVITY_SERVICE);
finalIActivityManageram= IActivityManager.Stub.asInterface(b);
return am;
}
};
复制代码
3、AMS.startService
AMS.startService函数获取调用Pid和Uid,然后调用ActiveService的startServiceLocked函数。
@Overridepublic ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)throws TransactionTooLargeException {
...
synchronized(this) {
finalintcallingPid= Binder.getCallingPid();
finalintcallingUid= Binder.getCallingUid();
finallongorigId= Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
复制代码
4、ActiveService.startServiceLock
ActiveService.startServiceLock函数,对一些合法性的检查,例如前台Service的权限、限制性后台Service进行延迟运行(standby)。并将要启动的信息封装成ServiceRecord。然后调用了startServiceInnerLocked函数。
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, finalint userId)throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, callingFeatureId, userId, false);
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, finalint userId,
boolean allowBackgroundActivityStarts)throws TransactionTooLargeException {
finalboolean callerFg;
if (caller != null) {
//获取调用Service的应用程序进程描述finalProcessRecordcallerApp= mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
...
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
//检索ServiceRecord,包括同应用和其他应用ServiceLookupResultres=
retrieveServiceLocked(service, null, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
...
//要启动的ServiceRecordServiceRecordr= res.record;
...
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(newServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));
ComponentNamecmp= startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
...
return cmp;
}
复制代码
5、ActiveServices.startServiceInnerLocker
调用了bringUpServiceLocked函数,会将ServiceRecord添加到ServiceMap类型的smap集合,进行缓存。
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
r.callStart = false;
...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
...
return r.name;
}
复制代码
6、 ActiveService.bringUpServiceLocked
分析一:首次启动Service时,在执行bringUpServiceLocked函数,ServiceRecord是属于新创建的,而非从AMS的缓存mServices中检索而来,所以此时的ServiceRecord的ProcessRecord类型app和IApplicationThread类型thread都是null。只有启动过后的ServiceRecord才有值,才会执行sendServiceArgsLocked函数,重复调用Service的生命周期onStartCommand,而不调用onCreate函数。
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)throws TransactionTooLargeException {
//分析一:未启动过的ServiceRecord两者都是null,重复启动会执行该函数,//会重复调用service的onStartCommand函数。if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
returnnull;
}
...
finalbooleanisolated= (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
finalStringprocName= r.processName;
HostingRecordhostingRecord=newHostingRecord("service", r.instanceName);
ProcessRecord app;
if (!isolated) {
通过AMS获取service所在进程的ProcessRecord。ProcessList=>MyProcessMap=》会缓存已创建过进程的ProcessRecord
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
//启动服务
realStartServiceLocked(r, app, execInFg);
returnnull;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
}
}
}
//如果service所在的进程未启动,通过AMS启动该进程,可以参考应用进程的启动流程if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {;
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
//等待进程启动完毕重启启动if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
...
returnnull;
}
复制代码
7、ActiveService.realStartServiceLocked
privatefinalvoidrealStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg)throws RemoteException {
//将ProcessRecord设置给ServiceRecord
r.setProcess(app);
//登记当ServiceRecord到ProcessRecordd的数组mServices,表示Service已经启动(实际未启动)finalbooleannewService= app.startService(r);
booleancreated=false;
try {
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
...
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app, "Died when creating service");
throw e;
}
//会调用Service的onStartCommand函数
sendServiceArgsLocked(r, execInFg, true);
...
}
复制代码
通过ProcessRecord对象的IApplicationThread引用,通过Binder机制调用了应用程序的ApplicationThread的scheduleCreateService函数。
8、ApplicationThread.scheduleCreateService
将ServiceInfo等相关信息封装到CreateServiceData中,并发送给ActivityThread的H类型的mH对象。
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);
}
复制代码
9、H.handleMesssage
调用了ActivityThread的handleCreateService函数。
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
复制代码
10、ActivityThread.handleCreateService
private void handleCreateService(CreateServiceData data) {
...
//获取当前应用的描述信息LoadedApk
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//创建Service的上下问文
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
//获取当前应用Applcation对象
Application app = packageInfo.makeApplication(false, mInstrumentation);
//通过反射创建Service对象
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
//初始化资源
context.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
//context 与service相互绑定
context.setOuterContext(service);
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Service的生命周期onCreate函数,意味Service创建完毕
service.onCreate();
//缓存Service
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);
}
}
}
复制代码
通过ContextImpl.createAppContext创建Service的上下文context,通过packageInfo.getAppFactory().instantiateService反射获得当前Service对象service,将context与service相互绑定。然后调用service.onCreate。至此,Service创建完毕。
二、Service的绑定
1、 ContextImpl.bindService
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
//系统进程调用绑定服务或发送广播都会发出警告warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}
复制代码
2、ContextImpl.bindServiceCommon
在分析一,主要判断入参Executor executor或UserHandle user哪个为null,总有一个为null,但最终都是调用了LoadedApk的getServiceDispatcherCommon函数来获取ServiceDispathcer类型sd。影响只是回调代码是在主线程执行,还是线程池。这里传入ActivityThread的H对象,意味着后续连接成功回调onServiceConnected是在主线程。
分析二:通过Binder机制调用AMS的bindIsolatedService函数。
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) {//分析一:无论哪个分支,都是获得ServiceConnect的本地引用sd,两者最终都是//调用LoadedApk的getServiceDispatcherCommon
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
//正常使用走这个分支
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
} else {
throw new RuntimeException("Not supported in system context");
}
//检查compant and package is null ?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);
//分析二:调用AMS.bindIsolatedService
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();
}
}
复制代码
IServiceConnection连接的创建会先从缓存中获取,避免每次都要新建。分析一:通过executor或handler创建ServiceDispatcher类型的sd,含有静态内部类InnerConnection的引用mIServiceConnection。继承自IServiceConnection.Stub,也就是InnerConnection是实现者,远程调用代理在其他进程,例如SystemServer进程中的ActiveService。
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) {
sd = map.get(c);
}
if (sd == null) {
//分析一:通过executor或handler创建ServiceDispatcher
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();
}
}
复制代码
3、AMS.bindIsolatedService
AMS经过两次重载函数bindIsolatedService调用,简单检查相关合法性。然后调用ActiveService类型的mService的bindServiceLocked函数。
4、ActiveService.bindServiceLocked
intbindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, finalint userId)throws TransactionTooLargeException {
//发起绑定service的app进程描述finalProcessRecordcallerApp= mAm.getRecordForAppLocked(caller);
...
ServiceLookupResultres=
retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true,
callerFg, isBindExternal, allowInstant);
...
ServiceRecords= res.record;
...
//描述Service和应用程序进程之间的关联,内部维护Service、进程、IntentFilter以及所有绑定信息。AppBindRecordb= s.retrieveAppBindingLocked(service, callerApp);
//描述应用程序与service建立的一次通信(绑定)ConnectionRecordc=newConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage);
IBinderbinder= connection.asBinder();
s.addConnection(binder, c);
b.connections.add(c);
if (activity != null) {
activity.addConnection(c);
}
b.client.connections.add(c);
c.startAssociationIfNeeded();
...
//启动Service,可以参考Service的启动if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return0;
}
}
...
//表示Service已启动,且已返回binder,可以通过binder访问接口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.shortInstanceName
+ " to connection " + c.conn.asBinder()
+ " (in " + c.binding.client.processName + ")", e);
}
//第一个绑定该Service的进程,且要重绑if (b.intent.apps.size() == 1 && b.intent.doRebind) {
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} elseif (!b.intent.requested) {//首次绑定,执行此次
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
...
}
复制代码
AppBindRecord 描述应用程序进程和Service的关联,包括谁绑定了Service的ProcessRecord,绑定信息IntentBindRecord,当前服务ServiceRecord,当前应用进程的所有连接记录connections。
5、requestServiceBindingLocked
调用了ApplicationThread的scheduleBindService函数。
privatefinalbooleanrequestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
...
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.getReportedProcState());
...
}
复制代码
6、ApplicationThread.scheduleBindService
将数据封装BindServiceData,发送个ActivityThread的H类型的mH处理。
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);
}
复制代码
7 、 H.handleMessage
case BIND_SERVICE:
handleBindService((BindServiceData)msg.obj);
复制代码
8、ActivityThread.handleBindService
handleBindService函数有两个分支,即是否重新绑定。
如果当前进程第一个与Service绑定,且调用过了onUbBinder方法,那么这里的data.rebind将为true,直接执行Service的onRebind函数即可。另外一种就是没有绑定过,那么需要执行Service的onBind函数。然后还要执行AMS的publishService函数。
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
...
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();
}
...
}
}
复制代码
9、AMS.publishService
publicvoidpublishService(IBinder token, Intent intent, IBinder service) {
// Refuse possible leaked file descriptorsif (intent != null && intent.hasFileDescriptors() == true) {
thrownewIllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
if (!(token instanceofServiceRecord)) {
thrownewIllegalArgumentException("Invalid service token");
}
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
复制代码
10、ActiveService.publishServiceLocked
分析一:可见在第4步bindServiceLocked函数,IntentBindRecord对象的属性binder、requested、received都是false。
在ServiceRecord的所有连接记录connections中,通过intent查找对应之前已经保存的ConnectionRecord,并调用其IServiceConnection的connected函数。
在第2步的时候调用bindServiceCommon函数时,会创建ServiceDispatcher时,内部持有InnerConnection实例,这里的IServiceConnection代理引用指向该InnerConnection实例,这里会调用其connected函数。
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) {//分析1
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)) {
...
continue;
}
...
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);
}
}
复制代码
11、InnerConnection.connected
private static classInnerConnectionextendsIServiceConnection.Stub{
@UnsupportedAppUsagefinalWeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = newWeakReference<LoadedApk.ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service, boolean dead)
throwsRemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
}
复制代码
12、ServiceDispatcher.connected
这里调用了 mActivityThread.post(new RunConnection(name, service, 0, dead)),执行RunConnection的run函数。这里的话run函数执行代码又回到了应用进程的主线程。
publicvoidconnected(ComponentName name, IBinder service, boolean dead) {
if (mActivityExecutor != null) {
mActivityExecutor.execute(newRunConnection(name, service, 0, dead));
} elseif (mActivityThread != null) {
mActivityThread.post(newRunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
复制代码
13、RunConnection.run
RunConnection是ServiceDispatcher的内部类,这里执行SD的doConnected函数。
public void run() {
if (mCommand == 0) {
doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
复制代码
14、ServiceDispatcher.doConnected
这里调用了ServiceConnection对象的onServiceConnected函数,也就是我们发起绑定,调用context.bindService的参数。
publicvoiddoConnected(ComponentName name, IBinder service, boolean dead) {
...
mConnection.onServiceConnected(name, service);
...
}
复制代码
到此,Service的绑定流程分析完毕。
三、Service的Context
在第一节Service的启动流程最后函数调用了ActivityThread的handleCreateService函数。
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
//应用的描述信息
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//分析一
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
Application app = packageInfo.makeApplication(false, mInstrumentation);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
context.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
//分析二
context.setOuterContext(service);
//分析三
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);
}
}
}
复制代码
分析一:通过ContextImpl的静态函数createAppContext返回了一个ContextImpl类型的context。createAppContext又调用了重载函数createAppContext。直接新建了ContextImpl实例context,构造函数传递了ActivityThread类型的mainThread和LoadedApk类型的packageInfo。并给context设置了资源环境和是否Syetem属性。
staticContextImplcreateAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
returncreateAppContext(mainThread, packageInfo, null);
}
staticContextImplcreateAppContext(ActivityThread mainThread, LoadedApk packageInfo,
String opPackageName) {
if (packageInfo == null) thrownewIllegalArgumentException("packageInfo");
ContextImpl context = newContextImpl(null, mainThread, packageInfo, null, null, null, null,
0, null, opPackageName);
context.setResources(packageInfo.getResources());
context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);
return context;
}
复制代码
ContextImpl类有一个Context类型的mOuterContext属性,在构造函数时指向了自己。
回到handleCreateService函数的分析二,在创建好Service对象service之后,将service作为参数传递给了context.setOuterContext函数。Service本身继承自ContextWrapper,ContextWrapper又是Context的子类。这时候的setOuterContext函数将service设置给了context的mOuterContext属性。意味着当前上下文context持有当前新建的service引用。
在分析三,调用了service.attach函数,context并作为第一个参数被传入。attach函数又调用了attachBaseContext函数。
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);mThread = thread; mClassName = className;mToken = token;mApplication = application;mActivityManager = (IActivityManager)activityManager;mStartCompatibility = getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ECLAIR;
setContentCaptureOptions(application.getContentCaptureOptions());
}
复制代码
attachBaseContext调用了父类ContextWrapper的attachBaseContext函数
@OverrideprotectedvoidattachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
if (newBase != null) {
newBase.setContentCaptureOptions(getContentCaptureOptions());
}
}
复制代码
ContextWrapper将一路传递过来的上下文base设置给你了mBase属性。
protectedvoidattachBaseContext(Context base) {
if (mBase != null) {
thrownew IllegalStateException("Base context already set");
}
mBase = base;
}
复制代码
也就是说,我们在启动Service时,会同时创建Service的上下文context,并将其存储到Service的父类ContextWrapper的mBases属性中,同时context也会有当前Service引用,存储在mOuterContext变量中。
四、总结
Service的启动和绑定从AMS转移到ActiveService
Service的启动,会先判断进程是否创建,提前启动进程,再启动自己。
Service重复启动,会重复调用onStratCommand及后续生命周期函数。
Service的绑定,会先走一趟Service的启动流程,再绑定。
应用进程与SytemServer进程(AMS、ActiveService)的交互式通过Binder机制进行,通过AIDL各持有双方接口。应用进程通过H对象,将现成重新切回主线程(所有应用夸进程通信应如此)。
Service在应用和AMS两边都会做缓存,以便快速在找到使用。应用程序存储在ArrayMap<IBinder, Service>类型的mServices;ActiveService则是ArraySet<ServiceRecord>类型的mServices。
作者:新小梦