Android应用启动流程分析
因为看了很多源码的实现,时间长了就遗忘了,所以做个简单记录,不会太详细。如果能对你能起到帮助那就更好了。
一、应用启动流程
只是记录了主要的流程节点
二、主要源码:
- launcher源码所在目录: package/apps/launcher2,因为最新源码 130G,下载编译又各种问题,最后痛心删掉重新下了8.0,所以所有代码都以8.0位依据,但核心功能应该不会有版本间太大变化
- 开始启动流程
boolean startActivity(View v, Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//核心代码 开始启动流程
try {
if (user == null || user.equals(android.os.Process.myUserHandle())) {
//如果已经有应用进程开启
startActivity(intent, opts.toBundle());
} else {
//构建应用启动页,并开启新的进程,通过ILauncherApps ibinder接口,获取系统
//LauncherAppsService 构建启动页,在启动流程中这个服务目前就做了这一件事
launcherApps.startMainActivity(intent.getComponent(), user,
intent.getSourceBounds(),
opts.toBundle());
}
return true;
} catch (SecurityException e) {
}
return false;
}
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
//execStartActivity 最为关键的方法, 通过该方法会通过IActivityManager 接口会通知,服务ActivityManagerService注册Activity
//startActivityFromChild主要是应用内启动页面,实例化windown 并加载docker
if (this.mParent == null) {
ActivityResult ar = this.mInstrumentation.execStartActivity(this, this.mMainThread.getApplicationThread(), this.mToken, this, intent, requestCode, options);
if (ar != null) {
this.mMainThread.sendActivityResult(this.mToken, this.mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
}
if (requestCode >= 0) {
this.mStartedActivity = true;
}
} else if (options != null) {
this.mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
this.mParent.startActivityFromChild(this, intent, requestCode);
}
}
ActivityManagerService 在源码中的路径以实现的接口
通过AMS startActivity 入口最终层层调用会走到 startProcessLocked方法,顾名思义开启新的进程
public static final Process.ProcessStartResult start(String processClass, String niceName, int uid, int gid, int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, zygoteArgs);
} catch (ZygoteStartFailedEx var11) {
Log.e("Process", "Starting VM process through Zygote failed");
throw new RuntimeException("Starting VM process through Zygote failed", var11);
}
}
private static Process.ProcessStartResult startViaZygote(String processClass, String niceName, int uid, int gid, int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String[] extraArgs) throws ZygoteStartFailedEx {
Class var10 = Process.class;
synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList();
argsForZygote.add("--runtime-init");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
if ((debugFlags & 16) != 0) {
argsForZygote.add("--enable-jni-logging");
}
if ((debugFlags & 8) != 0) {
argsForZygote.add("--enable-safemode");
}
if ((debugFlags & 1) != 0) {
argsForZygote.add("--enable-debugger");
}
if ((debugFlags & 2) != 0) {
argsForZygote.add("--enable-checkjni");
}
if ((debugFlags & 4) != 0) {
argsForZygote.add("--enable-assert");
}
if (mountExternal == 2) {
argsForZygote.add("--mount-external-multiuser");
} else if (mountExternal == 3) {
argsForZygote.add("--mount-external-multiuser-all");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
int len$;
int i$;
if (gids != null && gids.length > 0) {
StringBuilder sb = new StringBuilder();
sb.append("--setgroups=");
len$ = gids.length;
for(i$ = 0; i$ < len$; ++i$) {
if (i$ != 0) {
sb.append(',');
}
sb.append(gids[i$]);
}
argsForZygote.add(sb.toString());
}
if (niceName != null) {
argsForZygote.add("--nice-name=" + niceName);
}
if (seInfo != null) {
argsForZygote.add("--seinfo=" + seInfo);
}
argsForZygote.add(processClass);
if (extraArgs != null) {
String[] arr$ = extraArgs;
len$ = extraArgs.length;
for(i$ = 0; i$ < len$; ++i$) {
String arg = arr$[i$];
argsForZygote.add(arg);
}
}
return zygoteSendArgsAndGetResult(argsForZygote);
}
}```