值得用來學習的博客:
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
本文中時序圖的plant uml 源文件和簡化圖的draw.io的源文件共享在百度雲中
鏈接: https://pan.baidu.com/s/13rHVA5N7y26FUixv3SGfTw 提取碼: r3fa
簡單用圖表示下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名稱