一. 简介
要想启动一个应用,首先要保证这个应用所需要的进程已经启动过。AMS在启动一个应用的时候,事先会检查这个应用的进程是否存在, 不存在的话就会请求Zygote进程去fork一个新进程, 这样应用进程就会获得 Zygote进程在启动时创建的虚拟机实例.
当然在应用进程创建的过程中除了获取虚拟机实例外,还创建了Binder线程池和消息循环, 这样运行在应用进程中的应用程序就可以方便地使用Binder进行线程间通信以及处理消息了.
本篇文章流程的梳理是基于Android10源码. 阅读本篇文章前,请先阅读一下 Android 进程间通信机制(三) 系统进程与应用进程通信
二. 应用进程启动过程
应用进程创建的流程比较复杂, 这里分为两个步骤, 分别是AMS发送启动应用进程的请求,以及Zygote接收请求并创建应用进程.
2.1 AMS发送启动应用进程请求
这里先给出AMS发送启动应用进程请求过程的时序图:
AMS 如果想要启应用进程,就需要向Zygote进程发送创建应用进程的请求, AMS通过startProcessLocked方法向Zygote进程发送请求
// ActivityManagerService.java
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
接着调到ProcessList.java中的startProcessLocked方法 (13个参数)
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
//第一次走进来 isolated(孤立应用)是false,knownToBeDead是true
if (!isolated) {
//第一次进来app肯定是null
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkSlow(startTime, "startProcess: after getProcessRecord");
//设置了后台运行,桌面启动应用一般都不会走这里
if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
// If we are in the background, then check to see if this process
// is bad. If so, we will just silently fail.
//重新计算崩溃次数(crash大于等于2次服务将不会再启动)
if (mService.mAppErrors.isBadProcessLocked(info)) {
if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
+ "/" + info.processName);
return null;
}
} else {
// When the user is explicitly starting a process, then clear its
// crash count so that we won't make it bad until they see at
// least one crash dialog again, and make the process good again
// if it had been bad.
if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
+ "/" + info.processName);
mService.mAppErrors.resetProcessCrashTimeLocked(info);
if (mService.mAppErrors.isBadProcessLocked(info)) {
EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
UserHandle.getUserId(info.uid), info.uid,
info.processName);
mService.mAppErrors.clearBadProcessLocked(info);
if (app != null) {
app.bad = false;
}
}
}
} else {
// If this is an isolated process, it can't re-use an existing process.
app = null;
}
// We don't have to do anything more if:
// (1) There is an existing application record; and
// (2) The caller doesn't think it is dead, OR there is no thread
// object attached to it so we know it couldn't have crashed; and
// (3) There is a pid assigned to it, so it is either starting or
// already running.
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
+ " app=" + app + " knownToBeDead=" + knownToBeDead
+ " thread=" + (app != null ? app.thread : null)
+ " pid=" + (app != null ? app.pid : -1));
if (app != null && app.pid > 0) {
// UNISOC: bug1017202, Ensure the top activity host process been start successfully.
if ((!knownToBeDead && !app.killed)
|| (app.thread == null
&& !(mService.mActivityTaskManager.
isProcessStartedForTopActivity(app.getWindowProcessController())
&& app.killed))) {
// We already have the app running, or are waiting for it to
// come up (we have a pid but not yet its thread), so keep it.
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
checkSlow(startTime, "startProcess: done, added package to proc");
return app;
}
// An application record is attached to a previous process,
// clean it up now.
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
checkSlow(startTime, "startProcess: bad proc running, killing");
ProcessList.killProcessGroup(app.uid, app.pid);
mService.handleAppDiedLocked(app, true, true);
checkSlow(startTime, "startProcess: done killing old proc");
}
//第一次是走的这里 app为null
if (app == null) {
//这个是google的,用于调试卡顿的,不过除了特别有问题一般情况不会出现问题,
//50ms去掉系统或许更快,如果是给用户的稳定版本可以考虑把这段调试代码删除
checkSlow(startTime, "startProcess: creating new process record");
//此处是new ProcessRecord
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
return null;
}
app.crashHandler = crashHandler;
app.isolatedEntryPoint = entryPoint;
app.isolatedEntryPointArgs = entryPointArgs;
//新建ProcessRecord完成,该监控操作(newProcessRecordLocked)完成
checkSlow(startTime, "startProcess: done creating new process record");
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
checkSlow(startTime, "startProcess: added package to existing proc");
}
// If the system is not ready yet, then hold off on starting this
// process until it is.
if (!mService.mProcessesReady
&& !mService.isAllowedWhileBooting(info)
&& !allowWhileBooting) {
if (!mService.mProcessesOnHold.contains(app)) {
mService.mProcessesOnHold.add(app);
}
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
"System not ready, putting on hold: " + app);
checkSlow(startTime, "startProcess: returning with proc on hold");
return app;
}
checkSlow(startTime, "startProcess: stepping in to startProcess");
//开始启动进程
final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
checkSlow(startTime, "startProcess: done starting proc!");
return success ? app : null;
}
接着继续调用ProcessList中的startProcessLocked方法 (5个参数)
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
boolean disableHiddenApiChecks, boolean mountExtStorageFull,
String abiOverride) {
if (app.pendingStart) {
return true;
}
long startTime = SystemClock.elapsedRealtime();
//第一次启动app.pid == -1,不走这里
if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
checkSlow(startTime, "startProcess: removing from pids map");
mService.mPidsSelfLocked.remove(app);
mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
checkSlow(startTime, "startProcess: done removing from pids map");
app.setPid(0);
app.startSeq = 0;
}
if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
TAG_PROCESSES,
"startProcessLocked removing on hold: " + app);
mService.mProcessesOnHold.remove(app);
checkSlow(startTime, "startProcess: starting to update cpu stats");
//启动进程也会更新CPU状态
mService.updateCpuStats();
checkSlow(startTime, "startProcess: done updating cpu stats");
try {
try {
final int userId = UserHandle.getUserId(app.uid);
//用于检测是否可以启动,如:是否安装,是否正在冻屏等
AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
//isolated初始值是false
if (!app.isolated) {
int[] permGids = null;
try {
checkSlow(startTime, "startProcess: getting gids from package manager");
final IPackageManager pm = AppGlobals.getPackageManager();
//返回应用用户组的gid,如果是uid不一样,同一个应用该值也会不一样
permGids = pm.getPackageGids(app.info.packageName,
MATCH_DIRECT_BOOT_AUTO, app.userId);
if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) {
mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
} else {
StorageManagerInternal storageManagerInternal = LocalServices.getService(
StorageManagerInternal.class);
//获取应用读写外部存储的权限
//如果是孤立应用(uid是99000-99999)将返回MOUNT_EXTERNAL_NONE;
//能读返回MOUNT_EXTERNAL_READ,能写返回MOUNT_EXTERNAL_WRITE
mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
app.info.packageName);
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
......
......
//android:multiArch="true"代表所有架构都支持,一般都不设置,
//一般应用库文件需要判断是否32位还算64位,判断方法使用
//com_android_internal_content_NativeLibraryHelper.cpp的findSupportedAbi
//requiredAbi就是为了兼容32位&64位系统设计的
String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
if (requiredAbi == null) {
//此处如果应用没有设置实在32位还是64位运行的化,
//默认使用属性值ro.product.cpu.abilist的第一个值arm64-v8a(64bit),
//armeabi-v7a(32bit),armeabi(32bit)
requiredAbi = Build.SUPPORTED_ABIS[0];
}
String instructionSet = null;
if (app.info.primaryCpuAbi != null) {
//通过应用的库文件获取虚拟机要使用那种参数
instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
.....
.....
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
//将ActivityThread作为应用默认的入口函数entryPoint
final String entryPoint = "android.app.ActivityThread";
//此处才是调用Process.start启动进程的地方
boolean startSuccess = startProcessLocked(hostingRecord, entryPoint,
app, uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
.........
.........
}
继续调用ProcessList中的startProcessLocked方法 (12个参数)
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord,
String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
....
....
//创建预fork进程的参数
PreForkArgs preforkArgs = new PreForkArgs(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, app.seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
try {
//启动进程
final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
mService.notifyProcessStart(app.info.packageName, app.hostingRecord.getType(), startResult.pid);
mService.preforkStart(preforkArgs);
....
....
}
}
继续调用 startProcess方法(12个参数)
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
.....
.....
//通过log打印,走到是 else分支
startResult = mService.handlePreForkStartProcess(preforkArgs);
Slog.e("mytest", "==ProcessList 1900====else===");
if (startResult == null) {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
//modify for prefork blank process end
}
}
接下来,我们就查看Process的start方法
frameworks/base/core/java/android/os/Process.java
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
/*useUsapPool=*/ true, zygoteArgs);
}
在Process的start方法 调用了 ZygoteProcess start 方法,其中 zygoteProcess类
用于保持与 Zygote 进程的通信状态。该 start 方也如下所示:
frameworks/base/core/java/android/os/ZygoteProcess.java
public final Process.ProcessStartResult start(@NonNull final String processClass,
final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
boolean useUsapPool,
@Nullable String[] zygoteArgs) {
.....
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, useUsapPool, zygoteArgs);
.....
}
ZygoteProcess的 start方法调用了 startViaZygote方法 如下所示:
frameworks/base/core/java/android/os/ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
@Nullable final String niceName,
final int uid, final int gid,
@Nullable final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
boolean startChildZygote,
@Nullable String packageName,
boolean useUsapPool,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
.....
//创建字符串列表 argsForZygote ,并将应用进程的启动参数保存在argsForZygote中
ArrayList<String> argsForZygote = new ArrayList<>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
.....
synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
useUsapPool,
argsForZygote);
}
}
接下来就是与Zygote进程socket通信
@GuardedBy("mLock")
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
//与Zygote进程socket通信
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
}
}
好了,到这里,第一阶段就告一段落了.
2.2 Zygote 接收请求并创建应用程序进程
zygote 接收请求并建应用进程的时序图:
开机运行app_process进程(别称Zygote进程)
(init.zygote*.rc->app_process)->app_main.main->ZygoteInit.main
我们知道Zygote受精卵进程是由init进程创建,如下通过图可知:init进程是Zygote64受精卵进程的父进程,而system_server是通过zygote64受精卵进程创建的。(pid是该进程的id,ppid是其父进程的id)
我们先从ZygoteInit.java 的main方法看起
@UnsupportedAppUsage
public static void main(String argv[]) {
....
....
//启动system_server进程默认值是false
boolean startSystemServer = false;
//Socket的名字是zygote
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
//只有当传入的参数带有 start-system-server 时,才会启动,实质上系统只有初次开机的时候会启动, 其他都是去启动应用进程
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
//系统开机第一次会走这里,他就是区去fork system_server进程
//而我们是分析的创建应用进程,所以不会走这里
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
//而是走这里, 一直等待 AMS 请求创建新的应用进程
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList);
......
}
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*/
Runnable runSelectLoop(String abiList) {
....
//这里是一个while死循环
while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();
...
try {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
.....
}
这段代码所做工作:
1) 循环遍历等待Socket缓冲区有可读的数据
2) Socket.connect时会创建新的ZygoteConnection
3) ZygoteConnection执行processOneCommand方法
4) 创建子进程后,子进程退出循环,父进程继续等待下一个Socket数据
接下来继续去看 ZygoteConnection.java 的 processOneCommand方法
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
....
....
try {
//获取启动应用进程的参数
args = Zygote.readArgumentList(mSocketReader);
// TODO (chriswailes): Remove this and add an assert.
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
//创建应用进程
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
try {
//如果是子进程pid会等于0,父进程此处pid会返回子进程的pid
//当前代码逻辑运行在子进程中,(也就是新创建的应用进程)
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//处理应用进程的逻辑
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
//处理父进程逻辑
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
.....
}
如果 pid 等于0 则说明当前代码逻辑运行在新创建的子进程(应用进程 )中,这时就会调用 handleChildProc 方法来处理应用程序进程, 我们继续来看
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
....
//关闭自己的Socket
closeSocket();
//此处设置进程名字为之前传进来的processName
//设置进程的名字,这个时候通过ps就可以看到进程名字变成应用声明的进程(如果没有定义android:process那么默认该进程名字就是应用的包名)
if (parsedArgs.mNiceName != null) {
Process.setArgV0(parsedArgs.mNiceName);
}
...
} else {
if (!isZygote) {
//ZygoteInit.zygoteInit子进程的初始化
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
handleChildProc 方法中调用了 Zygotelnit的zygotelnit方法
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
....
//重新定向log的输入地方,此处设置log输出到Android log中
RuntimeInit.redirectLogStreams();
//一些通用设置的初始化
RuntimeInit.commonInit();
//在新的应用进程中创建Binder线程池
ZygoteInit.nativeZygoteInit();
//应用初始化,此处是接下来运行的地方
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
接下来就调用到了RuntimeInit.java 中的applicationInit方法:
frameworks/base/core/java/com/and oid/internal/os/Runtimelnit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
....
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
第一个参数 args.startClass,它指的就是上面提到的参数 android.app.ActivityThread
接下来去调用 findStaticMain 方法
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
try {
//获取android.app.ActivityThread类的 Class对象
cl = Class.forName(className, true, classLoader);
//通过反射获取ActivityThread.java的 main Method对象
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
//调用main方法
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//这里就跳转到 ActivityThread.java 的main方法了
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
.....
}
说到这里, 应用进程已经启动完成,将进入应用相关流程, 接下来看看 ActivityThread.java 的main方法中
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
//默认是没有用到SamplingProfilerIntegration的,
//该类用于监听性能数据,包含进程名字、应用信息、线程启动与关闭,
//还有默认persist.sys.profiler_ms毫秒dump一次该进程堆栈信息
SamplingProfilerIntegration.start();
//在严格模式或者调试的时候打开,默认不打卡
CloseGuard.setEnabled(false);
.......
//初始化环境(这里主要是存储设备的环境,用user id初始化)
Environment.initForCurrentUser();
//主要是libcore中使用event log的方法,Reporter的report类似于EventLog.writeEvent
EventLogger.setReporter(new EventLoggingReporter());
//配置文件目录在/data/misc/user/1000
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
//设置认证相关的目录cacerts-added,cacerts-removed
TrustedCertificateStore.setDefaultUserDirectory(configDir);
//设置进程名字为<pre-initialized>,这个很快在handleBindApplication时就会给修改
Process.setArgV0("<pre-initialized>");
//消息队列初始化,主进程是不允许退出的,无法调用MessageQueue.quit退出
Looper.prepareMainLooper();
.......
ActivityThread thread = new ActivityThread();
//新建一个ActivityThread并attach附着,这个跟接下去的attachApplication相关
thread.attach(false);
if (sMainThreadHandler == null) {
//获取thread的handler,将其作为应用的主线程
sMainThreadHandler = thread.getHandler();
}
if (false) {
//用户调试log,用于消息队列Message的事件分发log输出,
//调试消息队列的时候可以打开
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
//Looper.loop()里面是个for (;;)死循环,只要Message不为null,会一直运行
//Looper.loop() -> MessageQueue.next()
//-> nativePollOnce(android_os_MessageQueue.cpp)
//->(pollOnce/pollInner/epoll_wait) Looper.cpp,
//这个Message==null情况只有调用MessageQueue.quit才会发生,
//目前没有看到主动调用MessageQueue.quit,故这个消息队列循环是不会退出的
Looper.loop();
//如果进入到这里代表程序出错了,这里程序正常运行是不会进来的
throw new RuntimeException("Main thread loop unexpectedly exited");
}
三. 致谢
本文是基于Android10源码分析总结, 也参考了刘望舒<进阶解密>第三章内容, 时序图是根据源码绘制出来的,主线流程大体是正确的, 可以供大家参考,谢谢!
四. 待更新
后续有新的细节理解,再更新到文章来.