值得用来学习的博客:
Android Launcher 启动 Activity 的工作过程:https://blog.csdn.net/qian520ao/article/details/78156214
context.startActivity(intent) 7.0以下与7.0及以上的区别:https://blog.csdn.net/qq_20230661/article/details/82424199
android进阶之了解Zygote进程的启动及“孵化”:https://blog.csdn.net/XuJiaoJie/article/details/78890908
(Android 9.0)Activity启动流程源码分析:https://blog.csdn.net/lj19851227/article/details/82562115
简单用图表示下Activity的启动过程
详细的代码就不贴了,几个比较好的博客都介绍的很详细,这里做一个简洁的归纳整理,便于日后回顾。(基于Android 9.0)
一. 点击桌面图标启动Activity流程
同样的,Activity中启动Activity的方式与下相同。
1.1 简化流程
1.2 详细过程
一.点击桌面图片binder通知AMS去调度启动指定Activity,如果Activity进程不存在则AMS通过socket通知zygote去fork app子进程:
二.zygote fork子进程够子进程通过反射调用到ActivityThread的main方法:
三 .ActivityThread main方法中通知AMS将自己与之前AMS中创建的新的ProcessRecord关联起来,之后开始走Activity的生命周期:
二. context startActivity流程
1.1 简化过程
在service,receiver等非Activity的组建中起Activity的时候需要调用Context的startActivity方法启动对应的Activity
Context中同样调用Instrumentation的execStartActivity的方法,通过binder方式通知ActivityManagerService去启动Activity,之后方式与上相同,不再赘述。
这里注意 context.startActivity(intent) 7.0以下与7.0及以上的区别:https://blog.csdn.net/qq_20230661/article/details/82424199
三. am start Activity流程
3.1 简化过程
主要逻辑在
frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@Override
public int onCommand(String cmd) {
if (cmd == null) {
return handleDefaultCommands(cmd);
}
PrintWriter pw = getOutPrintWriter();
try {
switch (cmd) {
case "start":
case "start-activity":
return runStartActivity(pw);
case "startservice":
case "start-service":
return runStartService(pw, false);
case "startforegroundservice":
case "startfgservice":
case "start-foreground-service":
case "start-fg-service":
return runStartService(pw, true);
case "stopservice":
case "stop-service":
return runStopService(pw);
case "broadcast":
return runSendBroadcast(pw);
...
}
...
}
int runStartActivity(PrintWriter pw) throws RemoteException {
Intent intent;
try {
intent = makeIntent(UserHandle.USER_CURRENT);
} catch (URISyntaxException e) {
throw new RuntimeException(e.getMessage(), e);
}
if (mWaitOption) {
result = mInterface.startActivityAndWait(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
res = result.result;
} else {
res = mInterface.startActivityAsUser(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
}
...
}
mInterface即是AMS,之后启动和上述也基本一致了。
3.2 使用方式
am命令启动指定Activity
通过am start 命令可以启动指定Activity(在mainfest文件中声明的)
命令如下:
在adb shell 命令提示符下输入
am start -n com.example.yourpackage/com.example.activity.YourActivity
可以替换为自己的包名和Activity名称