Android10.0应用进程创建过程以及Zygote的fork流程-[Android取经之路]
阅读本文大约需要花费1小时。
文章的内容主要还是从源码进行分析,虽然又臭又长,但是如果想要学习Android系统源码,这是必要走的路,没有捷径。
相对于碎片学习,我更倾向于静下心来花费1个小时认真的学习一段内容。
系列文章:
Android系统启动之init进程(一)-「Android取经之路」
Android系统启动之init进程(二)-「Android取经之路」
Android 10.0系统启动之init进程(三)-「Android取经之路」
Android 10.0系统启动之init进程(四)-「Android取经之路」
Android 10.0系统启动之Zygote进程(一)-「Android取经之路」
Android 10.0系统启动之Zygote进程(二)-「Android取经之路」
Android 10.0系统启动之Zygote进程(三)-「Android取经之路」
Android 10.0系统启动之Zygote进程(四)-「Android取经之路」
Android 10.0系统启动之SystemServer进程(一)-「Android取经之路」
Android 10.0系统启动之SystemServer进程(二)-「Android取经之路」
Android 10.0系统服务之AMS启动流程-「Android取经之路」
Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]
1.概述
上一节我们学习了Launcher的启动流程。这一节来介绍下应用进程的创建过程以及Zygote Fork的过程。
点击桌面图标启动应用概述:
在上一节Launcher的启动中我们知道了,手机的桌面其实就是Launcher进程,里面的应用图标都是Launcher通过ListView进行展示。
那么我们点击一个桌面图标,比如微信,这个应用是如何启动的呢,这一节我们从系统级的源码来一步步的进行分析。
在分析之前,我们简单区分一下进程和线程的概念。
在Android中通过Logcat抓取log时,存在PID和TID两个概念。
PID:Process ID,进程ID
TID: Thread ID,线程ID
每个Android都是一个进程,每个进程有一个或多个线程
进程:
是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
当我们点击某个应用的图标时,必须创建一个进程,该进程是由Zygote fork出来的,进程具有独立的资源空间,用于承载App上运行的各种Activity/Service等组件。
线程:
是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
每个应用有多个线程,例如UI展示属于UI主线程,一些通信过程属于独立线程,通常JAVA中使用new Thread().start()来创建一个新的线程。
该线程并没有自己独立的地址空间,而是与其所在进程之间资源共享。
进程线程的区别
地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
资源拥有:同一进程内的线程共享本进程的资源,但是进程之间的资源是独立的。
一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
线程是处理器调度的基本单位,但是进程不是。
两者均可并发执行。
2.核心源码
/libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
/libcore/libart/src/main/java/java/lang/Daemons.java
/libcore/dalvik/src/main/java/dalvik/system/runtime.cc
/art/runtime/native/dalvik_system_ZygoteHooks.cc
/art/runtime/runtime.cc
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
/frameworks/base/core/java/android/os/Process.java
/frameworks/base/core/java/android/os/ZygoteProcess.java
/frameworks/base/core/java/android/app/LauncherActivity.java
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/Activity.java
/frameworks/base/core/java/android/app/ActivityManagerInternal.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
/frameworks/base/core/java/android/app/Instrumentation.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
3.架构
App发起进程:点击一个桌面应用(例如微信),Launcher 加载应用, LauncherActivity收到触发事件,组装Intent,通过binder发送消息给SystemServer进程,调用Activity的startActivity()来启动进程,启动Activity时,受ActivityManagerService-AMS的服务控制,AMS属于SystemServer进程,因此SystemServer进行会通过Process 来向Zygote发送一个Socket。
Zygote有一个无限循环,一直在等待Socket请求,收到SystemServer发来新的Socket请求后,Zygote调用系统的fork函数来孵化一个新的进程,比如这里的微信。
再把启动的入口交给ActivityThread,进入微信的进程中,进行详细的UI展示。
3.1 进程创建图
从点击Launcher中的图标,到启动Activity,再到Zygote Fork操作,最终进入新的进行进行UI绘制。
3.2 Zygote Fork图
Zygote调用系统的fork()函数,孵化出一个新的进程,fork()采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
图片来源Gityuan
4.源码分析
应用的启动共分以下四个步骤完成:
点击桌面的图标,Launcher调用系统的startActivity进行启动Activity,此时的动作在Launcher进程中
ATM\AMS 进行Activity的处理,组装message,通过socket发送给Socket
Zygote收到SystemServer发来的消息,进行消息拆分,再调用系统的fork()函数,进行进行孵化操作。
进入ActivityThread的main(),完成最终应用进程的的onCreate操作
接下来我们根据这四个步骤来进行详细的源码分析.
4.1 第一阶段,点击桌面图标,触发点击事件
触发Launcher listview的点击事件 onListItemClick()
说明:桌面图标按照5*5或者6*6的方式进行排列,这其实是Launcher进程展示的ListView,每个应用图标填入其中,点击图标进入Launcher的点击事件处理
源码:
[LauncherActivity.java] onListItemClick()
protected void onListItemClick(ListView l, View v, int position, long id) {
//ListView的点击事件也就是桌面的Icon的点击事件 ,这是整个启动流程的时间启动源。
Intent intent = intentForPosition(position); //构造一个Intent
startActivity(intent); //启动Activity,参考[4.1.1]
}
4.1.1 [Activity.java]
startActivity()
说明:这里比较简单,调用
startActivityForResult()
源码:
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
//调用startActivityForResult(),参考[4.1.2]
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
4.1.2 [Activity.java]
startActivityForResult()
说明:不难发现,不论有没有父Activity,最终都交给了 Instrumentation 来开启
源码:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
// Activity mParent; 其实是一个Activity ,
//判断是否有父类,没有父类的话交给Instrumentation
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
// 回调 ActivityResult
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
//最终调用的还是Instrumentation 的 execStartActivity(),参考[4.1.3]
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
4.1.3 [Instrumentation.java]
execStartActivity()
说明:Binder 调用 ActivityTaskManagerService-ATM 来启动 Activity
源码:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
// Binder 调用 ATM 来启动 Activity, 参考[4.2.1]
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// 检测启动结果
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
从下面代码可以看到,IActivityTaskManager其实获得的是activity_task对应服务的Binder对象,
即是ActivityTaskManagerService-ATM
[ActivityTaskManager.java]
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
//获取服务:ACTIVITY_TASK_SERVICE = "activity_task",对应的服务为ATM-ActivityTaskManagerService
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
4.2 第二阶段:ATM\AMS 进行Activity的处理
调用栈如下:
4.2.1 [ActivityTaskManagerService.java]
startActivity()
说明:这里很简单,直接调用startActivityAsUser()
源码:
public final int startActivity(IApplicationThread caller, ...) {
//参考[4.2.2]
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
4.2.2 [ActivityTaskManagerService.java]
startActivityAsUser()
说明:获取 ActivityStarter 对象,最终调用ActivityStarter的execute()
源码:
int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, ...) {
...
// 获取 ActivityStarter 对象,最终调用ActivityStarter的execute(), 参考[4.2.3]
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId) //这里调用了setMayWait(),因此ActivityStarter中的mRequest.mayWait为true
.execute();
}
4.2.3 [ActivityStarter.java] execute()
说明:根据[4.2.2]中调用了setMayWait,因此这里的mRequest.mayWait为true
源码:
int execute() {
try {
// setMayWait() 方法中将设置mayWait的值为true
//HomeActivity不设置,值为0
if (mRequest.mayWait) {
//应用进程走这一步,参考[4.2.4]
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
//Home Activity走这一步
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
4.2.4 [ActivityStarter.java]
startActivityMayWait()
说明:调用startActivity()来启动Activity
源码:
private int startActivityMayWait(IApplicationThread caller, ... WaitResult outResult,
...) {
...
final ActivityRecord[] outRecord = new ActivityRecord[1];
//调用startActivity()来启动Activity,参考[4.2.5]
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
...
//通知ActivityMetricsLogger,activity已经被启动起来
//ActivityMetricsLogger 将等待windows被绘制出来
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
if (outResult != null) {
// 设置启动结果
outResult.result = res;
final ActivityRecord r = outRecord[0];
switch(res) {
case START_SUCCESS: {
mSupervisor.mWaitingActivityLaunched.add(outResult);
do {
try {
// 启动成功,等待启动结果
mService.mGlobalLock.wait();
} catch (InterruptedException e) {
}
} while (outResult.result != START_TASK_TO_FRONT
&& !outResult.timeout && outResult.who == null);
if (outResult.result == START_TASK_TO_FRONT) {
res = START_TASK_TO_FRONT;
}
break;
}
...
}
}
return res;
}
}
4.2.5 [ActivityStarter.java]
startActivity()
说明:延时布局,然后通过startActivityUnchecked()来处理启动标记 flag ,要启动的任务栈等,最后恢复布局
源码:
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
...
try {
//延时布局
mService.mWindowManager.deferSurfaceLayout();
//调用 startActivityUnchecked ,一路调用到 resumeFocusedStacksTopActivities(),参考[4.2.6]
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
} finally {
//恢复布局
mService.mWindowManager.continueSurfaceLayout();
}
...
}
4.2.6 [RootActivityContainer.java]
resumeFocusedStacksTopActivities()
说明:获取栈顶的Activity,恢复它
源码:
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
//如果目标栈就是栈顶Activity,启动 resumeTopActivityUncheckedLocked()
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
...
if (!resumedOnDisplay) {
// 获取 栈顶的 ActivityRecord
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
//最终调用 startSpecificActivityLocked(),参考[4.2.7]
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
}
4.2.7 [ActivityStackSupervisor.java]
startSpecificActivityLocked()
说明:发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁,最终调用到ATM的startProcess()
源码:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
...
//发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁
//最终调用到AMS的startProcess(),参考[4.2.8]
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
...
}
4.2.8 [ActivityManagerService.java]
startProcess()
说明:一路调用Process start(),最终到ZygoteProcess的
attemptUsapSendArgsAndGetResult(),用来fork一个新的Launcher的进程
源码:
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName) {
..
//同步操作,避免死锁
synchronized (ActivityManagerService.this) {
//调用startProcessLocked,然后到 Process的start,最终到ZygoteProcess的attemptUsapSendArgsAndGetResult()
//用来fork一个新的Launcher的进程,参考[4.2.9]
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
...
}
调用栈如下:
4.2.9 [ZygoteProcess.java]
attemptZygoteSendArgsAndGetResult()
说明:通过Socket连接Zygote进程,把之前组装的msg发给Zygote,其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,
并执行 "android.app.ActivityThread"的main方法
源码:
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
//传入的zygoteState为openZygoteSocketIfNeeded(),里面会通过abi来检查是第一个zygote还是第二个
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
zygoteWriter.write(msgStr); //把应用进程的一些参数写给前面连接的zygote进程,包括前面的processClass ="android.app.ActivityThread"
zygoteWriter.flush(); //进入Zygote进程,处于阻塞状态, 参考[4.3]
//从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}
4.3 第三阶段 Zygote Fork 应用进程
说明:Zygote的启动过程我们前面有详细讲到过。
SystemServer的AMS服务向启动Home Activity发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。
由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。
fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
调用栈如下:
4.3.1 [ZygoteInit.java] main()
说明:Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher
源码:
public static void main(String argv[]) {
...
Runnable caller;
....
if (startSystemServer) {
//Zygote Fork出的第一个进程 SystmeServer
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
...
//循环等待fork出其他的应用进程,比如Launcher
//最终通过调用processOneCommand()来进行进程的处理,参考[4.3.2]
caller = zygoteServer.runSelectLoop(abiList);
...
if (caller != null) {
caller.run(); //执行返回的Runnable对象,进入子进程
}
}
4.3.2 [ZygoteConnection.java]
processOneCommand()
说明:通过 forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理
源码:
Runnable processOneCommand(ZygoteServer zygoteServer) {
int pid = -1;
...
//Fork子进程,得到一个新的pid
/fork子进程,采用copy on write方式,这里执行一次,会返回两次
///pid=0 表示Zygote fork子进程成功
//pid > 0 表示子进程 的真正的PID
//参考[4.3.3]
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);
...
if (pid == 0) {
// in child, fork成功,第一次返回的pid = 0
...
//参考[4.3.7]
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
//in parent
...
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
}
4.3.3 [Zygote.java] forkAndSpecialize
说明:主要是调用dalvik中ZygoteHooks的preFrok进行预处理,再调用postForkCommon进行完成的进程fork
源码:
public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
int targetSdkVersion) {
ZygoteHooks.preFork(); //参考[4.3.3.1]
//参考[4.3.5]
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir);
...
//参考[4.3.6]
ZygoteHooks.postForkCommon();
return pid;
}
4.3.3.1 [ZygoteHooks.java] preFork()
说明:Zygote进程有4个Daemon子线程分别是
HeapTaskDaemon、
ReferenceQueueDaemon、
FinalizerDaemon、
FinalizerWatchdogDaemon
preFork()预处理主要是先停止4个子线程,等待所有的子线程结束,最后完成gc堆的初始化工作
Zygote子线程如下图所示:
源码:
public void preFork() {
Daemons.stop(); //停止4个Daemon子线程,参考[4.3.3.2]
waitUntilAllThreadsStopped(); //等待所有子线程结束,参考[4.3.3.3]
token = nativePreFork(); //完成gc堆的初始化工作,参考[4.3.4]
}
4.3.3.2 [Daemons.java] stop()
说明:此处守护线程Stop方式是先调用目标线程interrrupt()方法,然后再调用目标线程join()方法,等待线程执行完成
停止4个子线程,分别是:Java堆整理线程;引用队列线程;析构线程;析构监控线程
源码:
private static final Daemon[] DAEMONS = new Daemon[] {
HeapTaskDaemon.INSTANCE, //Java堆整理线程
ReferenceQueueDaemon.INSTANCE, //引用队列线程
FinalizerDaemon.INSTANCE,//析构线程
FinalizerWatchdogDaemon.INSTANCE, //析构监控线程
};
public static void stop() {
for (Daemon daemon : DAEMONS) {
daemon.stop(); //循环停止线程
}
}
4.3.3.3 [ZygoteHooks.java]
waitUntilAllThreadsStopped()
说明:等待所有子线程结束
源码:
private static void waitUntilAllThreadsStopped() {
File tasks = new File("/proc/self/task");
// 当/proc中线程数大于1,就出让CPU直到只有一个线程,才退出循环
while (tasks.list().length > 1) {
Thread.yield();
}
}
4.3.4 [ZygoteHooks.java]
nativePreFork()
通过JNI最终调用的是以下方法:
[dalvik_system_ZygoteHooks.cc] ZygoteHooks_nativePreFork()
说明:进行堆的一些预处理
源码:
static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
Runtime* runtime = Runtime::Current();
CHECK(runtime->IsZygote()) << "runtime instance not started with -Xzygote";
runtime->PreZygoteFork(); //参考[4.3.4.1]
//将线程转换为long型并保存到token,该过程是非安全的
return reinterpret_cast<jlong>(ThreadForEnv(env));
}
4.3.4.1 [runtime.cpp] PreZygoteFork()
说明:堆的初始化工作,属于虚拟机的范畴,想理解的可以深挖一下
源码:
void Runtime::PreZygoteFork() {
if (GetJit() != nullptr) {
GetJit()->PreZygoteFork();
}
// 初始化堆的操作
heap_->PreZygoteFork();
}
4.3.5 [Zygote.java]
nativeForkAndSpecialize()
通过JNI最终调用的是以下方法:
[com_android_internal_os_Zygote.cpp] com_android_internal_os_Zygote_nativeForkAndSpecialize
说明: fork 子进程
源码:
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(...) {
...
//fork 应用进程,得到新的pid,fork()操作会有两次返回,第一次返回成功,pid=0
//第二次返回真正的pid
//参考[4.3.5.1]
pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
if (pid == 0) {
//上面第一次fork成功
//参考[4.3.5.2]
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
capabilities, capabilities,
mount_external, se_info, nice_name, false,
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir);
}
return pid;
}
4.3.5.1 [com_android_internal_os_Zygote.cpp]
ForkCommon()
说明:调用系统的fork()进行 应用进程的孵化操作,采用copy-on-write的机制,使得应用进程与Zygote共享部分数据,减少内存的占用
源码:
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,..) {
//设置子进程的signal
SetSignalHandlers();
...
//fork子进程,这里执行一次,会返回两次
//pid=0 表示Zygote fork SystemServer这个子进程成功
//pid > 0 表示SystemServer 的真正的PID
pid_t pid = fork();
if (pid == 0) {
//进入子进程
PreApplicationInit();
// 关闭并清除文件描述符
DetachDescriptors(env, fds_to_close, fail_fn);
ClearUsapTable();
...
} else {
ALOGD("Forked child process %d", pid);
}
return pid;
}
4.3.5.2 [com_android_internal_os_Zygote.cpp]
SpecializeCommon()
说明:进行进程的一些资源处理,selinux权限处理,并调用Zygote的callPostForkChildHooks()
源码:
static void SpecializeCommon(...){
...
if (!is_system_server && getuid() == 0) {
//对于非system_server子进程,则创建进程组
const int rc = createProcessGroup(uid, getpid());
...
}
SetGids(env, gids, fail_fn); //设置设置group
SetRLimits(env, rlimits, fail_fn); //设置资源limit
...
//selinux上下文
if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
...
}
...
//设置子进程的signal信号处理函数为默认函数
UnsetChldSignalHandler();
//等价于调用zygote.callPostForkChildHooks(), 参考[4.3.5.3]
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
is_system_server, is_child_zygote, managed_instruction_set);
}
4.3.5.3 [Zygote.java]
callPostForkChildHooks()
说明:JAVA堆线程的一些处理
源码:
private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
boolean isZygote, String instructionSet) {
ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
}
[ZygoteHooks.java] postForkChild
public void postForkChild(int runtimeFlags, boolean isSystemServer, boolean isZygote,
String instructionSet) {
//JNI调用到 ZygoteHooks_nativePostForkChild()
nativePostForkChild(token, runtimeFlags, isSystemServer, isZygote, instructionSet);
Math.setRandomSeedInternal(System.currentTimeMillis());
}
[dalvik_system_ZygoteHooks.cc] ZygoteHooks_nativePostForkChild()
static void ZygoteHooks_nativePostForkChild(...) {
Thread* thread = reinterpret_cast<Thread*>(token);
//设置新进程的主线程id
thread->InitAfterFork();
...
if (instruction_set != nullptr && !is_system_server) {
...
//调用runtime的InitNonZygoteOrPostFork()进行处理
Runtime::Current()->InitNonZygoteOrPostFork(
env, is_system_server, action, isa_string.c_str());
} else {
Runtime::Current()->InitNonZygoteOrPostFork(
env,
is_system_server,
Runtime::NativeBridgeAction::kUnload,
/*isa*/ nullptr,
profile_system_server);
}
}
创建JAVA的线程池,设置信号处理,启动JDWP线程
[runtime.cc] InitNonZygoteOrPostFork()
void Runtime::InitNonZygoteOrPostFork(...) {
is_zygote_ = false;
if (is_native_bridge_loaded_) {
switch (action) {
case NativeBridgeAction::kUnload:
UnloadNativeBridge(); //卸载用于跨平台的桥连库
is_native_bridge_loaded_ = false;
break;
case NativeBridgeAction::kInitialize:
InitializeNativeBridge(env, isa); //初始化用于跨平台的桥连库
break;
}
}
//创建Java堆处理的线程池
heap_->CreateThreadPool();
//重置gc性能数据,以保证进程在创建之前的GCs不会计算到当前app上。
heap_->ResetGcPerformanceInfo();
...
StartSignalCatcher();//设置信号处理函数
//启动JDWP线程,当命令debuger的flags指定"suspend=y"时,则暂停runtime
ScopedObjectAccess soa(Thread::Current());
GetRuntimeCallbacks()->StartDebugger();
}
4.3.6 [ZygoteHooks.java] postForkCommon()
说明:在fork新进程后,启动Zygote的4个Daemon线程,java堆整理,引用队列,以及析构线程。
源码:
public void postForkCommon() {
Daemons.startPostZygoteFork();
nativePostZygoteFork();
}
启动Zygote的4个新的子线程
[Daemons.java]
private static final Daemon[] DAEMONS = new Daemon[] {
HeapTaskDaemon.INSTANCE, //Java堆整理线程
ReferenceQueueDaemon.INSTANCE, //引用队列线程
FinalizerDaemon.INSTANCE, //析构线程
FinalizerWatchdogDaemon.INSTANCE, //析构监控线程
};
public static void startPostZygoteFork() {
postZygoteFork = true;
for (Daemon daemon : DAEMONS) {
daemon.startPostZygoteFork();
}
}
4.3.7 [ZygoteConnection.java]
handleChildProc()
说明:进行子进程的操作,最终获得需要执行的ActivityThread的main()
源码:
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.mInvokeWith != null) {
...
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
// App进程将会调用到这里,执行目标类的main()方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
zygoteInit 进行一些环境的初始化、启动Binder进程等操作
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
RuntimeInit.commonInit(); //初始化运行环境
ZygoteInit.nativeZygoteInit(); //启动Binder线程池
//调用程序入口函数
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
把之前传来的"android.app.ActivityThread" 传递给findStaticMain
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
// startClass: 如果AMS通过socket传递过来的是 ActivityThread
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
通过反射,拿到ActivityThread的main()方法
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用
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;
}
//调用ActivityThread的main()
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
至此,Zygote fork进程的操作全部完成,下一步进入JAVA世界,进行真正的Activity的启动流程。
4.4 第四阶段 进入应用进程,启动Activity的onCreate()
调用栈如下:
4.4.1 [ActivityThread.java] main()
说明: 主线程处理, 创建ActivityThread对象,调用attach进行处理,最终进入Looper循环
源码:
public static void main(String[] args) {
// 安装选择性的系统调用拦截
AndroidOs.install();
...
//主线程处理
Looper.prepareMainLooper();
...
//之前SystemServer调用attach传入的是true,这里到应用进程传入false就行
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
...
//一直循环,如果退出,说明程序关闭
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
调用ActivityThread的attach进行处理
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//应用进程启动,走该流程
...
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//获取AMS的本地代理类
final IActivityManager mgr = ActivityManager.getService();
try {
//通过Binder调用AMS的attachApplication方法,参考[4.4.2]
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
//通过system_server启动ActivityThread对象
...
}
// 为 ViewRootImpl 设置配置更新回调,
//当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化
ViewRootImpl.ConfigChangedCallback configChangedCallback
= (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
...
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
4.4.2 [ActivityManagerService.java]
attachApplication()
说明:清除一些无用的记录,最终调用ActivityStackSupervisor.java的 realStartActivityLocked(),进行Activity的启动
源码:
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
//通过Binder获取传入的pid信息
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
//如果当前的Application记录仍然依附到之前的进程中,则清理掉
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}·
//mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,
//所以这里的normalMode也为true
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
...
//上面说到,这里为true,进入StackSupervisor的attachApplication方法
//去真正启动Activity
if (normalMode) {
...
//调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
//参考[4.4.3]
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
...
}
...
return true;
}
4.4.3 [ActivityStackSupervisor.java]
realStartActivityLocked()
说明:真正准备去启动Activity,通过clientTransaction.addCallback把LaunchActivityItem的obtain作为回调参数加进去,再调用
ClientLifecycleManager.scheduleTransaction()得到LaunchActivityItem的execute()方法进行最终的执行
参考上面的第四阶段的调用栈流程:
源码:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 直到所有的 onPause() 执行结束才会去启动新的 activity
if (!mRootActivityContainer.allPausedActivitiesComplete()) {
...
return false;
}
try {
// Create activity launch transaction.
// 添加 LaunchActivityItem
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
//LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
...
// 设置生命周期状态
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
// 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法
//参考[4.4.4]
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
} catch (RemoteException e) {
if (r.launchFailed) {
// 第二次启动失败,finish activity
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
}
// 第一次失败,重启进程并重试
r.launchFailed = true;
proc.removeActivity(r);
throw e;
}
} finally {
endDeferResume();
}
...
return true;
}
4.4.4 [TransactionExecutor.java] execute()
说明:执行之前realStartActivityLocked()中的
clientTransaction.addCallback
调用栈:
源码:
public void execute(ClientTransaction transaction) {
...
// 执行 callBack,参考上面的调用栈,执行回调方法,
//最终调用到ActivityThread的handleLaunchActivity()参考[4.4.5]
executeCallbacks(transaction);
// 执行生命周期状态
executeLifecycleState(transaction);
mPendingActions.clear();
}
4.4.5 [ActivityThread.java]
handleLaunchActivity()
说明:主要干了两件事,第一件:初始化WindowManagerGlobal;第二件:调用performLaunchActivity方法
源码:
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
//初始化WindowManagerGlobal
WindowManagerGlobal.initialize();
...
//调用performLaunchActivity,来处理Activity,参考[4.4.6]
final Activity a = performLaunchActivity(r, customIntent);
..
return a;
}
4.4.6 [ActivityThread.java]
performLaunchActivity()
说明:获取ComponentName、Context,反射创建Activity,设置Activity的一些内容,比如主题等;
最终调用callActivityOnCreate()来执行Activity的onCreate()方法
源码:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 获取 ComponentName
ComponentName component = r.intent.getComponent();
...
// 获取 Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 反射创建 Activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
...
}
try {
// 获取 Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
...
//Activity的一些处理
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
...
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
// 设置主题
activity.setTheme(theme);
}
activity.mCalled = false;
// 执行 onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
r.activity = activity;
}
//当前状态为ON_CREATE
r.setState(ON_CREATE);
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
return activity;
}
callActivityOnCreate先执行activity onCreate的预处理,再去调用Activity的onCreate,最终完成Create创建后的内容处理
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity); //activity onCreate的预处理
activity.performCreate(icicle, persistentState);//执行onCreate()
postPerformCreate(activity); //activity onCreate创建后的一些信息处理
}
performCreate()主要调用Activity的onCreate()
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
至此,看到了我们最熟悉的Activity的onCreate(),应用启动的启动完成,应用程序被真正的调用起来。
5.总结
通过上面一系列的流程,我们理解了应用进程的创建流程,以及Zygote fork这些应用进程的流程。
主要分为4步完成:
点击桌面的图标,Launcher调用系统的startActivity进行启动Activity,此时的动作在Launcher进程中
通过Binder向SystemServer进行发送消息,让ATM\AMS 进行Activity的处理,组装message,通过socket发送给Socket,此时动作在SystemServer进程中
Zygote收到SystemServer发来的消息,进行消息拆分,再调用系统的fork()函数,进行进行孵化操作,此时动作在Zygote进程中
进入ActivityThread的main(),完成最终应用进程的的onCreate操作,该步动作处于新创建的应用进程中