本文基于Android api 26
主要从进程角度记录启动Service的流程
文章目录
1 第一次跨进程调用:ContextImpl —> AMS
调用栈
Activity#startService()
ContextImpl#startService()
ContextImpl#startServiceCommon()
ContextImpl#startServiceCommon()
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
1.1 AMS中的startService()
调用过程
AMS#startService()
ActiveServices#startServiceLocked()
ActiveServices#startServiceInnerLocked()
ActiveServices#bringUpServiceLocked()
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//1 不用生成新的Process,直接在已有的进程内运行服务
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
} else {
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingType = "webview_service";
}
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired) {
//2 通过AMS创建新进程
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, r.name, 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;
}
}
}
AMS#startProcessLocked()
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
if (app == null) {
checkTime(startTime, "startProcess: creating new process record");
//1 创建ProcessRecord对象
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
return null;
}
}
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
//2 请求Zygote生成android.app.ActivityThread进程
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
//3 以pid为键 将ProcessRecord保存到AMS中的mPidsSelfLocked中
this.mPidsSelfLocked.put(startResult.pid, app);
}
1.2 ActivityThread启动新进程
public final class ActivityThread {
//创建ApplicationThread对象
final ApplicationThread mAppThread = new ApplicationThread();
final H mH = new H();
private class H extends Handler {
public void handleMessage(Message msg) {
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;
case UNBIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
handleUnbindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}
final Handler getHandler() {
return mH;
}
}
2 第二次跨进程调用:ActivityThread —> AMS
传递ApplicationThread对象
ActivityThread#attach()
private void attach(boolean system) {
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
2.1 AMS中的attachApplication()
AMS#attachApplication()
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
AMS#attachApplicationLocked()
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
//获取生成ActivityThread的pid值的ProcessRecord
ProcessRecord app;
app = mPidsSelfLocked.get(pid);
//内部赋值即:app.thread = thread
app.makeActive(thread, mProcessStats);
}
ActiveServices#attachApplicationLocked()
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
ServiceRecord sr = null;
for (int i=0; i<mPendingServices.size(); i++) {
//获取运行服务的ServiceRecord
sr = mPendingServices.get(i);
mPendingServices.remove(i);
i--;
proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
mAm.mProcessStats);
realStartServiceLocked(sr, proc, sr.createdFromFg);
}
}
3 第三次跨进程调用: AMS —> ApplicationThread
3.1 ActiveServices中的realStartServiceLocked
ActiveServices#realStartServiceLocked()
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
}
3.2 ApplicationThread中的scheduleCreateService()
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);
}
3.3 调用Service的生命周期方法
private void handleCreateService(CreateServiceData data) {
oadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
service.onCreate();
}
4 AMS中的mPidsSelfLocked
此对象是用于保存pid和ApplicationThread对象映射关系
final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
其key为pidValue为ProcessRecord对象,ProcessRecord对象中有ApplicationThread成员变量,所以AMS可以通过pid获取到对应的ApplicationThread对象进而控制Activity,Service等的生命周期