Android10.0系統啓動之Launcher(桌面)啓動流程-[Android取經之路]

摘要:上一節我們講完了Android10.0的ActivityManagerService的啓動流程,在AMS的最後啓動了Launcher進程,今天我們就來看看Launcher的真正啓動流程。

 

閱讀本文大約需要花費50分鐘。

文章的內容主要還是從源碼進行分析,雖然又臭又長,但是如果想要學習Android系統源碼,這是必要走的路,沒有捷徑。

相對於碎片學習,我更傾向於靜下心來花費1個小時認真的學習一段內容。

文章首發微信公衆號:IngresGe

專注於Android系統級源碼分析,Android的平臺設計,歡迎關注我,謝謝!

 

[Android取經之路] 的源碼都基於Android-Q(10.0) 進行分析

[Android取經之路] 系列文章:

《系統啓動篇》

  1. Android系統架構
  2. Android是怎麼啓動的
  3. Android 10.0系統啓動之init進程
  4. Android10.0系統啓動之Zygote進程
  5. Android 10.0 系統啓動之SystemServer進程
  6. Android 10.0 系統服務之ActivityMnagerService
  7. Android10.0系統啓動之Launcher(桌面)啓動流程
  8. Android10.0應用進程創建過程以及Zygote的fork流程
  9. Android 10.0 PackageManagerService(一)工作原理及啓動流程
  10. Android 10.0 PackageManagerService(二)權限掃描
  11. Android 10.0 PackageManagerService(三)APK掃描
  12. Android 10.0 PackageManagerService(四)APK安裝流程

《日誌系統篇》

  1. Android10.0 日誌系統分析(一)-logd、logcat 指令說明、分類和屬性
  2. Android10.0 日誌系統分析(二)-logd、logcat架構分析及日誌系統初始化
  3. Android10.0 日誌系統分析(三)-logd、logcat讀寫日誌源碼分析
  4. Android10.0 日誌系統分析(四)-selinux、kernel日誌在logd中的實現​

《Binder通信原理》

  1. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
  2. Android10.0 Binder通信原理(二)-Binder入門篇
  3. Android10.0 Binder通信原理(三)-ServiceManager篇
  4. Android10.0 Binder通信原理(四)-Native-C\C++實例分析
  5. Android10.0 Binder通信原理(五)-Binder驅動分析
  6. Android10.0 Binder通信原理(六)-Binder數據如何完成定向打擊
  7. Android10.0 Binder通信原理(七)-Framework binder示例
  8. Android10.0 Binder通信原理(八)-Framework層分析
  9. Android10.0 Binder通信原理(九)-AIDL Binder示例
  10. Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub設計模式​​​​​​​​​​​​​​
  11. Android10.0 Binder通信原理(十一)-Binder總結

1.概述

    上一節我們學習了AMS\ATM的啓動流程,這一節主要來學習Launcher的啓動流程。

    在Android的中,桌面應用Launcher由Launcher演變到Launcher2,再到現在的Launcher3,Google也做了很多改動。

    Launcher不支持桌面小工具動畫效果,Launcher2添加了動畫效果和3D初步效果支持,從Android 4.4 (KK)開始Launcher默認使用Launcher3,    Launcher3加入了透明狀態欄,增加overview模式,可以調整workspace上頁面的前後順序,可以動態管理屏幕數量,widget列表與app list分開顯示等功能。

  我們主要研究Launcher3的啓動過程。

2.核心源碼

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
/frameworks/base/core/java/android/os/Process.java
/frameworks/base/core/java/android/os/ZygoteProcess.java
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/Activity.java
/frameworks/base/core/java/android/app/ActivityManagerInternal.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
/frameworks/base/core/java/android/app/Instrumentation.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

從上面的代碼路徑可以看出,Android10.0中 Activity的相關功能被放到了wm的目錄中在Android9.0中是在am目錄中Google 最終的目的是把activity 和window融合,在Android10中只是做了簡單的代碼路徑的變更,正在的功能還要到後面的版本才能慢慢融合。

主要代碼作用:

  • Instrumentation:

        負責調用Activity和Application生命週期。

  • ActivityTaskManagerService:

        負責Activity管理和調度等工作。
        ATM是Android10中新增內容

  • ActivityManagerService:

        負責管理四大組件和進程,包括生命週期和狀態切換。

  • ActivityTaskManagerInternal:

    是由ActivityTaskManagerService對外提供的一個抽象類,真正的實現是在 ActivityTaskManagerService#LocalService

  • ActivityThread:

        管理應用程序進程中主線程的執行

  • ActivityStackSupervisor:

        負責所有Activity棧的管理

  • TransactionExecutor:

        主要作用是執行ClientTransaction

  • ClientLifecycleManager:

        生命週期的管理調用

 

3.架構

Android啓動流程圖:

 

Launcher啓動序列圖:

    內容較多,例如Zygote的fork流程,realStartActivityLocked啓動Activity的中間過程,都沒有列出,下一個章節會單獨來講這部分內容

 

4.源碼分析

    上一節在AMS啓動過程中,我們知道了AMS啓動完成前,在systemReady()中會去調用startHomeOnAllDisplays()來啓動Launcher,本次就從startHomeOnAllDisplays()函數入口,來看看Launcher是如何被啓動起來的。

[ActivityManagerService.java]
public void systemReady(final Runnable goingCallback, TimingsTraceLog 
traceLog) {
    ...
    //啓動Home Activity
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ...
}

Launcher的啓動由三部分啓動:

  1. SystemServer完成啓動Launcher Activity的調用

  2. Zygote()進行Launcher進程的Fork操作

  3. 進入ActivityThread的main(),完成最終Launcher的onCreate操作

接下來我們分別從源碼部分來分析這三個啓動過程。

 

4.1第一階段SystemServer 啓動HomeActivity的調用階段

調用棧:

[ActivityTaskManagerService.java] startHomeOnAllDisplays()

說明:ActivityTaskManagerInternal是 ActivityTaskManagerService的一個抽象類,正在的實現是在ActivityTaskManagerService的LocalService,所以mAtmInternal.startHomeOnAllDisplays()最終調用的是ActivityTaskManagerService的startHomeOnAllDisplays()方法

源碼:

public boolean startHomeOnAllDisplays(int userId, String reason) {
          synchronized (mGlobalLock) {
         //一路調用到 RootActivityContainer 的startHomeOnDisplay()方法,參考[4.2]
        return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
     }
}

4.2 [RootActivityContainer.java] startHomeOnDisplay()

說明:在[4.1]中,獲取的displayId爲DEFAULT_DISPLAY, 首先通過getHomeIntent 來構建一個category爲CATEGORY_HOME的Intent,表明是Home Activity;然後通過resolveHomeActivity()從系統所用已安裝的引用中,找到一個符合HomeItent的Activity,最終調用startHomeActivity()來啓動Activity

源碼:

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
    boolean fromHomeKey) {
    ...
     if (displayId == DEFAULT_DISPLAY) {
        //構建一個category爲CATEGORY_HOME的Intent,表明是Home Activity,參考[4.2.1]
        homeIntent = mService.getHomeIntent();
        //通過PKMS從系統所用已安裝的引用中,找到一個符合HomeItent的Activity參考[4.2.2]
        aInfo = resolveHomeActivity(userId, homeIntent); 
    } 
    ...
    //啓動Home Activity,參考[4.3]
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
        displayId);
    return true;
}

4.2.1 [ActivityTaskManagerService.java] getHomeIntent()

說明:構建一個category爲CATEGORY_HOME的Intent,表明是Home Activity。

Intent.CATEGORY_HOME = "android.intent.category.HOME"

這個category會在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity

源碼:

Intent getHomeIntent() {
    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    //不是生產模式,add一個CATEGORY_HOME
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    return intent;
}

4.2.2 [RootActivityContainer.java] resolveHomeActivity()

說明:通過Binder跨進程通知PackageManagerService從系統所用已安裝的引用中,找到一個符合HomeItent的Activity

源碼:

ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
    final int flags = ActivityManagerService.STOCK_PM_FLAGS;
    final ComponentName comp = homeIntent.getComponent(); //系統正常啓動時,component爲null
    ActivityInfo aInfo = null;
    ...
        if (comp != null) {
            // Factory test.
            aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
        } else {
            //系統正常啓動時,走該流程
            final String resolvedType =
                    homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
            
            //resolveIntent做了兩件事:1.通過queryIntentActivities來查找符合HomeIntent需求Activities
            //            2.通過chooseBestActivity找到最符合Intent需求的Activity信息
            final ResolveInfo info = AppGlobals.getPackageManager()
                    .resolveIntent(homeIntent, resolvedType, flags, userId);
            if (info != null) {
                aInfo = info.activityInfo;
            }
        }
    ...
    aInfo = new ActivityInfo(aInfo);
    aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
    return aInfo;
}

4.3 [ActivityStartController.java ] startHomeActivity()

說明:正在的啓動Home Activity入口。obtainStarter() 方法返回的是 ActivityStarter 對象,它負責 Activity 的啓動,一系列 setXXX() 方法傳入啓動所需的各種參數,最後的 execute() 是真正的啓動邏輯。另外如果home activity處於頂層的resume activity中,則Home Activity 將被初始化,但不會被恢復。並將保持這種狀態,直到有東西再次觸發它。我們需要進行另一次恢復。   

源碼:

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
    ....
    //返回一個 ActivityStarter 對象,它負責 Activity 的啓動
    //一系列 setXXX() 方法傳入啓動所需的各種參數,最後的 execute() 是真正的啓動邏輯
    //最後執行 ActivityStarter的execute方法
    mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
            .setOutActivity(tmpOutRecord)
            .setCallingUid(0)
            .setActivityInfo(aInfo)
            .setActivityOptions(options.toBundle())
            .execute();  //參考[4.3.1]
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    final ActivityDisplay display =
            mService.mRootActivityContainer.getActivityDisplay(displayId);
    final ActivityStack homeStack = display != null ? display.getHomeStack() : null;

    if (homeStack != null && homeStack.mInResumeTopActivity) {
        //如果home activity 處於頂層的resume activity中,則Home Activity 將被初始化,但不會被恢復(以避免遞歸恢復),
        //並將保持這種狀態,直到有東西再次觸發它。我們需要進行另一次恢復。
        mSupervisor.scheduleResumeTopActivities();
    }
}

4.3.1 [ActivityStarter.java] execute()

說明:在[4.3]中obtainStarter沒有調用setMayWait的方法,因此mRequest.mayWait爲false,走startActivity流程

源碼:

int execute() {
    ...
    if (mRequest.mayWait) {
        return startActivityMayWait(...)
    } else {
         return startActivity(...) //參考[4.3.2]
    }
    ...
}

4.3.2 [ActivityStarter.java] startActivity()

說明:延時佈局,然後通過startActivityUnchecked()來處理啓動標記 flag ,要啓動的任務棧等,最後恢復佈局

源碼:

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
    ...
    try {
        //延時佈局
        mService.mWindowManager.deferSurfaceLayout();
        //調用 startActivityUnchecked ,一路調用到resumeFocusedStacksTopActivities(),參考[4.3.4]
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
    } finally {
        //恢復佈局
        mService.mWindowManager.continueSurfaceLayout();
    }
    ...
}

4.3.3 [RootActivityContainer.java]  resumeFocusedStacksTopActivities()

說明:獲取棧頂的Activity,恢復它

源碼:

boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    //如果秒錶棧就是棧頂Activity,啓動resumeTopActivityUncheckedLocked()
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
        || getTopDisplayFocusedStack() == targetStack)) {
    result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    ...
    if (!resumedOnDisplay) {
        // 獲取  棧頂的 ActivityRecord
        final ActivityStack focusedStack = display.getFocusedStack();
        if (focusedStack != null) {
            //最終調用startSpecificActivityLocked(),參考[4.3.4]
            focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
    }
  }
}

4.3.4 [ActivityStackSupervisor.java]  startSpecificActivityLocked()

說明:發佈消息以啓動進程,以避免在ATM鎖保持的情況下調用AMS時可能出現死鎖,最終調用到ATM的startProcess()

源碼:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    ...
    //發佈消息以啓動進程,以避免在ATM鎖保持的情況下調用AMS時可能出現死鎖
    //最終調用到AMS的startProcess(),參考[4.3.5]
    final Message msg = PooledLambda.obtainMessage(
            ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
            r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
    mService.mH.sendMessage(msg);
    ...
}

4.3.5 [ActivityManagerService.java] startProcess()

說明:一路調用Process start(),最終到ZygoteProcess的attemptUsapSendArgsAndGetResult(),用來fork一個新的Launcher的進程

源碼:

public void startProcess(String processName, ApplicationInfo info,        boolean knownToBeDead, String hostingType, ComponentName hostingName) {        ..        //同步操作,避免死鎖        synchronized (ActivityManagerService.this) {            //調用startProcessLocked,然後到 Process的start,最終到ZygoteProcess的attemptUsapSendArgsAndGetResult()            //用來fork一個新的Launcher的進程,參考[4.3.6]            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,                    new HostingRecord(hostingType, hostingName),                    false /* allowWhileBooting */, false /* isolated */,                    true /* keepIfLarge */);        }        ...}

調用棧如下:

4.3.6 [ZygoteProcess.java]  attemptZygoteSendArgsAndGetResult()

說明:通過Socket連接Zygote進程,把之前組裝的msg發給Zygote,其中processClass ="android.app.ActivityThread",通過Zygote進程來Fork出一個新的進程,並執行 "android.app.ActivityThread"的main方法

源碼:

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        //傳入的zygoteState爲openZygoteSocketIfNeeded(),裏面會通過abi來檢查是第一個zygote還是第二個
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
        final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

        zygoteWriter.write(msgStr);  //把應用進程的一些參數寫給前面連接的zygote進程,包括前面的processClass ="android.app.ActivityThread"
        zygoteWriter.flush(); //進入Zygote進程,處於阻塞狀態, 參考[4.4]

         //從socket中得到zygote創建的應用pid,賦值給 ProcessStartResult的對象
        Process.ProcessStartResult result = new Process.ProcessStartResult();
        result.pid = zygoteInputStream.readInt();
        result.usingWrapper = zygoteInputStream.readBoolean();

        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }

        return result;
    } catch (IOException ex) {
        zygoteState.close();
        Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                + ex.toString());
        throw new ZygoteStartFailedEx(ex);
    }
}

4.4  第二階段Zygote fork一個Launcher進程的階段

說明:Zygote的啓動過程我們前面有詳細講到過。SystemServer的AMS服務向啓動Home Activity發起一個fork請求,Zygote進程通過Linux的fork函數,孵化出一個新的進程。

    由於Zygote進程在啓動時會創建Java虛擬機,因此通過fork而創建的Launcher程序進程可以在內部獲取一個Java虛擬機的實例拷貝。fork採用copy-on-write機制,有些類如果不做改變,甚至都不用複製,子進程可以和父進程共享這部分數據,從而省去不少內存的佔用。

    fork過程,參考下圖:

Zygote的調用棧如下:

4.4.1 [ZygoteInit.java] main()

說明:Zygote先fork出SystemServer進程,接着進入循環等待,用來接收Socket發來的消息,用來fork出其他應用進程,比如Launcher

源碼:

public static void main(String argv[]) {
    ...
    Runnable caller;
    ....
    if (startSystemServer) {
        //Zygote Fork出的第一個進程 SystmeServer
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

        if (r != null) {
            r.run();
            return;
        }
    }
    ...
    //循環等待fork出其他的應用進程,比如Launcher
    //最終通過調用processOneCommand()來進行進程的處理,參考[4.4.2]
    caller = zygoteServer.runSelectLoop(abiList);
    ...
    if (caller != null) {
        caller.run(); //執行返回的Runnable對象,進入子進程
    }
}

4.4.2 [ZygoteConnection.java] processOneCommand()

說明:通過forkAndSpecialize()來fork出Launcher的子進程,並執行handleChildProc,進入子進程的處理

源碼:

Runnable processOneCommand(ZygoteServer zygoteServer) {
    int pid = -1;
    ...
    //Fork子進程,得到一個新的pid
    /fork子進程,採用copy on write方式,這裏執行一次,會返回兩次
    ///pid=0 表示Zygote  fork子進程成功
    //pid > 0 表示子進程 的真正的PID
    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
            parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
            parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
    ...
    if (pid == 0) {
        // in child, fork成功,第一次返回的pid = 0
        ...
        //參考[4.4.3]
        return handleChildProc(parsedArgs, descriptors, childPipeFd,
                parsedArgs.mStartChildZygote);
    } else {
        //in parent
        ...
        childPipeFd = null;
        handleParentProc(pid, descriptors, serverPipeFd);
        return null;
    }
}

4.4.3 [ZygoteConnection.java] handleChildProc()

說明:進行子進程的操作,最終獲得需要執行的ActivityThread的main()

源碼:

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
        FileDescriptor pipeFd, boolean isZygote) {
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            // App進程將會調用到這裏,執行目標類的main()方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}

zygoteInit 進行一些環境的初始化、啓動Binder進程等操作:

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    RuntimeInit.commonInit(); //初始化運行環境 
    ZygoteInit.nativeZygoteInit(); //啓動Binder線程池 
     //調用程序入口函數  
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

把之前傳來的"android.app.ActivityThread" 傳遞給findStaticMain:

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ...
    // startClass: 如果AMS通過socket傳遞過來的是 ActivityThread
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

通過反射,拿到ActivityThread的main()方法:

protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    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);
    }
    return new MethodAndArgsCaller(m, argv);
}

把反射得來的ActivityThread main()入口返回給ZygoteInit的main,通過caller.run()進行調用:


static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    //調用ActivityThread的main()
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

4.5 第三個階段,Launcher在自己的進程中進行onCreate等後面的動作

    從[4.4]可以看到,Zygote fork出了Launcher的進程,並把接下來的Launcher啓動任務交給了ActivityThread來進行,接下來我們就從ActivityThread main()來分析Launcher的創建過程。

調用棧如下:

4.5.1 [ActivityThread.java] main()

說明:主線程處理, 創建ActivityThread對象,調用attach進行處理,最終進入Looper循環

源碼:

public static void main(String[] args) {
    // 安裝選擇性的系統調用攔截
    AndroidOs.install();
  ...
  //主線程處理
    Looper.prepareMainLooper();
  ...
  
  //之前SystemServer調用attach傳入的是true,這裏到應用進程傳入false就行
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
  ...
  //一直循環,如果退出,說明程序關閉
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

調用ActivityThread的attach進行處理

private void attach(boolean system, long startSeq) {
  sCurrentActivityThread = this;
  mSystemThread = system;
  if (!system) {
    //應用進程啓動,走該流程
    ...
    RuntimeInit.setApplicationObject(mAppThread.asBinder());
     //獲取AMS的本地代理類
    final IActivityManager mgr = ActivityManager.getService();
    try {
      //通過Binder調用AMS的attachApplication方法,參考[4.5.2]
      mgr.attachApplication(mAppThread, startSeq);
    } catch (RemoteException ex) {
      throw ex.rethrowFromSystemServer();
    }
    ...
  } else {
    //通過system_server啓動ActivityThread對象
    ...
  }

  // 爲 ViewRootImpl 設置配置更新回調,
  當系統資源配置(如:系統字體)發生變化時,通知系統配置發生變化
  ViewRootImpl.ConfigChangedCallback configChangedCallback
      = (Configuration globalConfig) -> {
    synchronized (mResourcesManager) {
      ...
    }
  };
  ViewRootImpl.addConfigCallback(configChangedCallback);
}

4.5.2  [ActivityManagerService.java]  attachApplication()

說明:清除一些無用的記錄,最終調用ActivityStackSupervisor.java的 realStartActivityLocked(),進行Activity的啓動

源碼:

public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
    //通過Binder獲取傳入的pid信息
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
  ...
    //如果當前的Application記錄仍然依附到之前的進程中,則清理掉
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }·

    //mProcessesReady這個變量在AMS的 systemReady 中被賦值爲true,
    //所以這裏的normalMode也爲true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
  ...
    //上面說到,這裏爲true,進入StackSupervisor的attachApplication方法
    //去真正啓動Activity
    if (normalMode) {
    ...
      //調用ATM的attachApplication(),最終層層調用到ActivityStackSupervisor.java的 realStartActivityLocked()
      //參考[4.5.3]
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
    ...
    }
  ...
    return true;
}

4.5.3 [ActivityStackSupervisor.java] realStartActivityLocked()

說明:真正準備去啓動Activity,通過clientTransaction.addCallback把LaunchActivityItem的obtain作爲回調參數加進去,再調用

ClientLifecycleManager.scheduleTransaction()得到

LaunchActivityItem的execute()方法進行最終的執行

    參考上面的第三階段的調用棧流程

    調用棧如下:

源碼:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
     // 直到所有的 onPause() 執行結束纔會去啓動新的 activity
    if (!mRootActivityContainer.allPausedActivitiesComplete()) {
    ...
        return false;
    }
  try {
            // Create activity launch transaction.
            // 添加 LaunchActivityItem
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
      //LaunchActivityItem.obtain(new Intent(r.intent)作爲回調參數
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                    r.icicle, r.persistentState, results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                            r.assistToken));

      ...
      // 設置生命週期狀態
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            // 重點關注:調用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法
      //參考[4.5.4]
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);

        } catch (RemoteException e) {
            if (r.launchFailed) {
                 // 第二次啓動失敗,finish activity
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }
            // 第一次失敗,重啓進程並重試
            r.launchFailed = true;
            proc.removeActivity(r);
            throw e;
        }
    } finally {
        endDeferResume();
    }
  ...
    return true;
}

4.5.4 [TransactionExecutor.java] execute()

說明:執行之前realStartActivityLocked()中的 

clientTransaction.addCallback

源碼:

 [TransactionExecutor.java] 
public void execute(ClientTransaction transaction) {
  ...
     // 執行 callBack,參考上面的調用棧,執行回調方法,
   //最終調用到ActivityThread的handleLaunchActivity()參考[4.5.5]
    executeCallbacks(transaction);

     // 執行生命週期狀態
    executeLifecycleState(transaction);
    mPendingActions.clear();
}

4.5.5 [ActivityThread.java]  handleLaunchActivity()

說明:主要乾了兩件事,第一件:初始化WindowManagerGlobal;第二件:調用performLaunchActivity方法

源碼:

[ActivityThread.java] 
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
  ...
  //初始化WindowManagerGlobal
    WindowManagerGlobal.initialize();
  ...
  //調用performLaunchActivity,來處理Activity,參考[4.5.6]
    final Activity a = performLaunchActivity(r, customIntent);
  ..
    return a;
}

4.5.6 [ActivityThread.java] performLaunchActivity()

說明:獲取ComponentName、Context,反射創建Activity,設置Activity的一些內容,比如主題等; 最終調用callActivityOnCreate()來執行Activity的onCreate()方法

源碼:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
     // 獲取 ComponentName
    ComponentName component = r.intent.getComponent();
  ...
     // 獲取 Context
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
         // 反射創建 Activity
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
    ...
    }

    try {
        // 獲取 Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
      ...
      //Activity的一些處理
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback,
                    r.assistToken);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
      ...
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
              // 設置主題
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            // 執行 onCreate()
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
      ...
            r.activity = activity;
        }
    //當前狀態爲ON_CREATE
        r.setState(ON_CREATE);
    ...
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
    ...
    }
    return activity;
}

callActivityOnCreate先執行activity onCreate的預處理,再去調用Activity的onCreate,最終完成Create創建後的內容處理

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity); //activity onCreate的預處理
    activity.performCreate(icicle, persistentState);//執行onCreate()
    postPerformCreate(activity); //activity onCreate創建後的一些信息處理
}

performCreate()主要調用Activity的onCreate()

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
  ...
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
  ...
}

至此,看到了我們最熟悉的Activity的onCreate(),Launcher的啓動完成,Launcher被真正創建起來。

 

5.總結

看到onCreate()後,進入到我們最熟悉的Activity的入口,Launcher的啓動告一段落。整個Android的啓動流程,我們也完整的分析完成。

Launcher的啓動經過了三個階段:

第一個階段:SystemServer完成啓動Launcher Activity的調用

第二個階段:Zygote()進行Launcher進程的Fork操作

第三個階段:進入ActivityThread的main(),完成最終Launcher的onCreate操作

 

下一節會來分析一下Android的進程創建過程以及Zygote的fork流程。

 

微信公衆號:IngresGe

 

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