[Android Fk] Activity啓動簡單梳理(基於P)

值得用來學習的博客:
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名稱

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章