源码分析->应用进程启动过程
分析从fork进程到Application onCreate执行的过程。
源码分析基于Android 23
1.大体过程
1.1 在Launch点击按钮启动A应用, Launch应用与AMS之间是binder通信;
1.2 AMS向Zygote进程请求创建A应用进程,AMS与Zygote之间是Socket通信;
1.3 Zygote通过fork创建A应用进程,并调用ActivityThread.main方法;
1.4 ActivityThread.main()中创建ApplicationThread并注册到AMS,A应用与AMS之间是binder通信;
1.5 AMS请求A应用执行Application onCreate方法,AMS与A应用之间是binder通信。
2.源码分析
我们知道,在Launch点击按键启动A应用,将触发Activity.startActivity,中间经过很多调用,我们关注最终会调到ActivityStackSupervisor.startSpecificActivityLocked
该方法是启动进程的入口,主要工作:
(1)getProcessRecordLocked,通过进程名获取ProcessRecord;
(2)如果进程启动,则if (app != null && app.thread != null)条件成立,realStartActivityLocked通过跨进程调用启动A应用;
(3)如果进程没有启动,则mService.startProcessLocked,请求AMS启动进程,我们跟进mService.startProcessLocked方法;
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {//进程启动了
try {
......
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
//进程没有启动
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
上述的startProcessLocked最终会调到
ActivityManagerService.startProcessLocked
主要工作:
(1) entryPoint赋值为android.app.ActivityThread,这里就相当熟悉了,后面会通过反射来调用它的main方法;
(2) 调用Process.start来创建进程,返回结果为startResult ,我们跟进去这个方法看看;
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
......
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
......
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
......
}
Process.start->Process.startViaZygote
主要工作:
(1)配置虚拟机的参数,包括ActivityThread的全类名;
(2)openZygoteSocketIfNeeded会调用ZygoteState.connect与Zygote进程建立Socket连接;
(3)zygoteSendArgsAndGetResult,socket连接成功,则发送数据。
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
argsForZygote.add("--enable-jni-logging");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
argsForZygote.add("--enable-safemode");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
argsForZygote.add("--enable-debugger");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
argsForZygote.add("--enable-checkjni");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
argsForZygote.add("--enable-jit");
}
if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
argsForZygote.add("--generate-debug-info");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
argsForZygote.add("--enable-assert");
}
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
argsForZygote.add("--mount-external-read");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
argsForZygote.add("--mount-external-write");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
......
argsForZygote.add(processClass);//ActivityThread的全类名
......
zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
......
return ;
}
}
Socket的服务端在ZygoteInit类中,
(1)runSelectLoop,接收请求由ZygoteConnection.runOnce来处理,我们跟进去看看;
(2)巧妙地利用异常来反射调用ActivityThread.main,MethodAndArgsCaller 异常是封装了反射调用ActivityThread.main。
public static void main(String argv[]) {
......
runSelectLoop(abiList);
......
} catch (MethodAndArgsCaller caller) {
caller.run(); //巧妙的利用异常处理,来反射执行ActivityThread.main()
}
......
}
ZygoteConnection.runOnce->ZygoteConnection.forkAndSpecialize
主要工作:
(1)Zygote.forkAndSpecialize,内部通过native方法fork进程;
(2)handleChildProc,内部调用RuntimeInit.zygoteInit,我们跟进去看看;
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
......
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
......
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
......
}
RuntimeInit.zygoteInit
主要工作:
(1)nativeZygoteInit,启动binder机制:打开binder驱动,映射内存,注册binder线程,进入binder looper;
(2)applicationInit,内部调用RuntimeInit.invokeStaticMain;
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
......
commonInit();
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
RuntimeInit.invokeStaticMain
主要的工作:
(1)反射方法的校验,类是否存在、方法是否存在、方法是否静态以及public;
(2)最后抛出一个异常ZygoteInit.MethodAndArgsCaller,回到上述的ZygoteInit.main。
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
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);
}
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
ZygoteInit.MethodAndArgsCaller.run
主要工作:
通过反射来调用ActivityThread.main;
public void run() {
......
mMethod.invoke(null, new Object[] { mArgs });
......
}
至此,启动工作转到了ActivityThread.main。
ActivityThread.main()
主要工作:
(1) Looper.prepareMainLooper(),初始化主线程消息队列;
(2)构造ActivityThread,调用attach方法,其中包括把ApplicationThread注册到AMS;
(3)Looper.loop(),启动消息队列;
public static void main(String[] args) {
......
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
......
Looper.loop();
......
}
}
ActivityThread.attach()
主要工作:
mgr.attachApplication(mAppThread),告知AMS,App启动完成。mAppThread是一个Binder对象,是AMS与App通信的入口;
private void attach(boolean system) {
......
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
......
}
ActivityManagerService.attachApplication->ActivityManagerService.attachApplicationLocked
主要工作:
跨进程调用 thread.bindApplication,thread是ApplicationThread类型;
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
......
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
......
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
......
}
ApplicationThread.bindApplication
主要工作:
sendMessage(H.BIND_APPLICATION, data),将任务转到主线程,会调到handleBindApplication方法。
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
......
AppBindData data = new AppBindData();
......
sendMessage(H.BIND_APPLICATION, data);
}
ActivityThread.handleBindApplication
主要工作:
(1)cl.loadClass(data.instrumentationName.getClassName()).newInstance(),通过反射实例化Instrumentation,这是进程单例;
(2)data.info是LoadeApk类型,对应着一个apk文件,通过makeApplication来构建Application实例,并且会创建ContextImpl通过attachBaseContext赋值给mBase;
(3)callApplicationOnCreate,通过mInstrumentation来调用Application onCreate方法。
private void handleBindApplication(AppBindData data) {
......
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}//这段代码比较有意思,如果版本是3.1,AsyncTask使用多线程的线程池,包括3.1,否则使用单线程的线程池
......
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
......
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
......
mInstrumentation.callApplicationOnCreate(app);
}
至此,B应用的Application onCreate方法被调用。
进程启动流程1.png进程启动流程2.png
3.总结
(1)ActivityStackSupervisor.startSpecificActivityLocked是fork应用进程的入口,如果ProcessRecord以及ApplicationThread都为空则需要fork进程;
(2)Process.start与Zygote进行Socket连接,请求fork进程;
(3)Zygote接收到请求,调用ZygoteConnection.runOnce方法处理for请求;
(4)进程启动以后,把反射调用ActivityThread.main方法封装一个MethodAndArgsCaller异常对象抛出,ZygoteInit捕获异常并执行;
(5)ActivityThread.main启动主线程Looper、构建ActivityThread、进入Looper循环;
(6)ActivityThread.attch向AMS注册ApplicationThread;
(7)AMS跨进程调用ApplicationThread.bindApplication;
(8)ApplicationThread发消息到主线程,ActivityThread创建Application对象,给成员变量mBase赋值,最后调用其onCreate方法。
常见面试题:
1.谈谈你对Application的理解
(1)作用
Application生命周期很长,注意持有短生命对象,导致内存泄漏;
可以在onCreate方法中做一些初始化的工作,但要考虑进程启动速度;
提供全局的上下文,不用担心内存泄漏问题;
多进程应用,就有多个Application实例;
(2)继承关系
继承ContextWrapper,最终是继承Context,有一个mBase全局变量。
(3)调用顺序
构造函数、attachBaseContext、onCreate。
2.进程启动完成的标志
ProcessRecord、ApplicationThread不为空,并且已经向ams注册了ApplicationThread;
、,
3.应用binder机制是什么时候启动的
RuntimeInit.zygoteInit会调用nativeZygoteInit,启动binder机制:打开binder驱动,映射内存,注册binder线程,进入binder looper;
4.为什么采用fork的方式
为了资源复用和加快启动速度,因为Zygote已经preLoad过一些常用的资源(常用类、常用库、常用资源),应用进程无需再加载。
以上分析有不对的地方,请指出,互相学习,谢谢哦!