Android Application 啟動(dòng)流程分析及其源碼調(diào)用探究

一、寫(xiě)在前面

在開(kāi)始之前,你需要知道下面幾點(diǎn):

  • 有一份編譯好的 Android 源碼,現(xiàn)在的 AS 基本能滿足,動(dòng)手跟著步驟走,理解更深刻
  • 對(duì) Binder 機(jī)制有一定的了解
  • 本文基于 API 26,用什么版本的源碼并不重要,大體的流程并無(wú)本質(zhì)上的區(qū)別
  • 從用戶手指觸摸點(diǎn)擊桌面圖標(biāo)到 Activity 啟動(dòng)

關(guān)鍵類簡(jiǎn)介

  • ActivityManagerService:AMS 是 Android 中最核心的服務(wù)之一,主要負(fù)責(zé)系統(tǒng)中四大組件的啟動(dòng)、切換、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度等工作,其職責(zé)與操作系統(tǒng)中的進(jìn)程管理和調(diào)度模塊相類似,它本身也是一個(gè) Binder 的實(shí)現(xiàn)類,應(yīng)用進(jìn)程能通過(guò) Binder 機(jī)制調(diào)用系統(tǒng)服務(wù)。
  • ActivityThread:應(yīng)用的入口類,系統(tǒng)通過(guò)調(diào)用main函數(shù),開(kāi)啟消息循環(huán)隊(duì)列。ActivityThread 所在線程被稱為應(yīng)用的主線程(UI 線程)。
  • Instrumentation:工具類,它用來(lái)監(jiān)控應(yīng)用程序和系統(tǒng)的交互,包裝了 ActivityManagerService 的調(diào)用,一些插件化方案就是通過(guò) hook 該類實(shí)現(xiàn)的。
  • ActivityStarter:Activity 啟動(dòng)的工具類,處理啟動(dòng) Activity 的各種 flag 。
  • ActivityStackSupervisor:管理所有應(yīng)用的 Activity 的棧,其中 mFocusedStack 就是當(dāng)前應(yīng)用的 Activity 棧。

應(yīng)用進(jìn)程介紹

  • 在大多數(shù)情況下,每個(gè) Android 應(yīng)用都在各自的 Linux 進(jìn)程中運(yùn)行。當(dāng)需要運(yùn)行應(yīng)用的一些代碼時(shí),系統(tǒng)會(huì)為應(yīng)用創(chuàng)建此進(jìn)程,并使其保持運(yùn)行,直到不再需要它且系統(tǒng)需要回收其內(nèi)存以供其他應(yīng)用使用。
  • 應(yīng)用進(jìn)程的生命周期并不由應(yīng)用本身直接控制,而是由系統(tǒng)綜合多種因素來(lái)確定的,比如系統(tǒng)所知道的正在運(yùn)行的應(yīng)用部分、這些內(nèi)容對(duì)用戶的重要程度,以及系統(tǒng)中可用的總內(nèi)存量。這是 Android 非常獨(dú)特的一個(gè)基本功能。
  • 當(dāng)應(yīng)用組件啟動(dòng)且該應(yīng)用未運(yùn)行任何其他組件時(shí),Android 系統(tǒng)會(huì)使用單個(gè)執(zhí)行線程為應(yīng)用啟動(dòng)新的 Linux 進(jìn)程。默認(rèn)情況下,同一應(yīng)用的所有組件會(huì)在相同的進(jìn)程和線程(稱為“主”線程)中運(yùn)行。如果某個(gè)應(yīng)用組件啟動(dòng)且該應(yīng)用已存在進(jìn)程(因?yàn)榇嬖谠搼?yīng)用的其他組件),則該組件會(huì)在此進(jìn)程內(nèi)啟動(dòng)并使用相同的執(zhí)行線程。但是,您可以安排應(yīng)用中的其他組件在單獨(dú)的進(jìn)程中運(yùn)行,并為任何進(jìn)程創(chuàng)建額外的線程。
  • 每個(gè)應(yīng)用進(jìn)程都相當(dāng)于一個(gè) Sandbox 沙箱,Android 通過(guò)對(duì)每一個(gè)應(yīng)用分配一個(gè) UID,注意這里的 UID 不同于 Linux 系統(tǒng)的 User ID,可以將每個(gè)應(yīng)用理解為一個(gè) User ,只能對(duì)其目錄下的內(nèi)容具有訪問(wèn)和讀寫(xiě)權(quán)限。
  • Android 利用遠(yuǎn)程過(guò)程調(diào)用 (RPC) 提供了一種進(jìn)程間通信 (IPC) 機(jī)制,在此機(jī)制中,系統(tǒng)會(huì)(在其他進(jìn)程中)遠(yuǎn)程執(zhí)行由 Activity 或其他應(yīng)用組件調(diào)用的方法,并將所有結(jié)果返回給調(diào)用方。因此,您需將方法調(diào)用及其數(shù)據(jù)分解至操作系統(tǒng)可識(shí)別的程度,并將其從本地進(jìn)程和地址空間傳輸至遠(yuǎn)程進(jìn)程和地址空間,然后在遠(yuǎn)程進(jìn)程中重新組裝并執(zhí)行該調(diào)用。然后,返回值將沿相反方向傳輸回來(lái)。Android 提供執(zhí)行這些 IPC 事務(wù)所需的全部代碼,因此您只需集中精力定義和實(shí)現(xiàn) RPC 編程接口。

下面這張圖可以補(bǔ)充理解一下進(jìn)程的概念:


進(jìn)程隔離及通信

二、流程分析

先來(lái)一張流程簡(jiǎn)圖:


app 啟動(dòng)流程簡(jiǎn)圖

下面是流程詳細(xì)圖,帶你看完整個(gè)啟動(dòng)流程及其所涉及到的類:


app 啟動(dòng)流程詳細(xì)圖

下面補(bǔ)充一張 Gityuan 大神的系統(tǒng)啟動(dòng)架構(gòu)圖幫助理解,其實(shí)只要看看這張圖的上半部分就足夠了:


android-boot

三、概述

簡(jiǎn)單地講,從 用戶手指觸摸點(diǎn)擊桌面圖標(biāo)到 Activity啟動(dòng) 可以用下面 4 步概括:

  1. 當(dāng)點(diǎn)擊桌面 App 的時(shí)候,發(fā)起進(jìn)程就是 Launcher 所在的進(jìn)程,啟動(dòng)遠(yuǎn)程進(jìn)程,利用 Binder 發(fā)送消息給 system_server 進(jìn)程;
  1. 在 system_server 中,啟動(dòng)進(jìn)程的操作會(huì)先調(diào)用
    ActivityManagerService#startProcessLocked() 方法,該方法內(nèi)部調(diào)用 Process.start(android.app.ActivityThread);而后通過(guò) socket 通信告知 Zygote 進(jìn)程 fork 子進(jìn)程,即 app 進(jìn)程。進(jìn)程創(chuàng)建后將 ActivityThread 加載進(jìn)去,執(zhí)行 ActivityThread#main()方法;
  1. 在 app 進(jìn)程中,main() 方法會(huì)實(shí)例化 ActivityThread,同時(shí)創(chuàng)建 ApplicationThread,Looper,Handler 對(duì)象,調(diào)用 ActivityThread#attach(false) 方法進(jìn)行 Binder 通信,方法里面調(diào)用 ActivityManagerService#attachApplication(mAppThread) 方法,將 thread 信息告知 ActivityManagerService , 接著 Looper 啟動(dòng)循環(huán);
  1. 回到 system_server 中,ActivityManagerService#attachApplication(mAppThread) 方法內(nèi)部調(diào)用了 thread#bindApplication()mStackSupervisor#attachApplicationLocked() 我們依次講解這兩個(gè)方法;
    4.1 thread#bindApplication() 方法調(diào)用了 ActivityThread#sendMessage(H.BIND_APPLICATION, data) 方法,最終走到了 ActivityThread#handleBindApplication(),進(jìn)而創(chuàng)建 Application 對(duì)象,然后調(diào)用 Application#attach(context) 來(lái)綁定 Context ,創(chuàng)建完 Application 對(duì)象后便是調(diào)用 mInstrumentation#callApplicationOnCreate() 執(zhí)行 Application#onCreate() 生命周期;
    4.2 mStackSupervisor#attachApplicationLocked() 方法中調(diào)用 app#thread#scheduleLaunchActivity()ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法,進(jìn)而通過(guò) ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最終走到了 ActivityThread#handleLaunchActivity() ,進(jìn)而創(chuàng)建 Activity 對(duì)象,然后調(diào)用 activity.attach() 方法,再調(diào)用 mInstrumentation#callActivityOnCreate() 執(zhí)行 Activity#onCreate() 生命周期;

四、源碼調(diào)用探究

對(duì)應(yīng)本文第一張流程圖的每一個(gè)步驟,下面逐步來(lái)看看源碼是怎么調(diào)用的:

STEP 1

用戶點(diǎn)擊 app 圖標(biāo);

STEP 2

Launcher 捕獲點(diǎn)擊事件,調(diào)用 Activity#startActivity()

STEP 3

Activity#startActivity() 調(diào)用 Instrumentation;

Activity.java

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            ···
        } else {
            ···
        }
    }

STEP 4

Instrumentation 通過(guò) Binder 通信發(fā)送消息給 system_server 進(jìn)程,具體 調(diào)用 ActivityManager#getService()#startActivity() ,ActivityManager#getService() 的具體實(shí)現(xiàn)是 ActivityManagerService ;

Instrumentation.java

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ···
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

ActivityManager.java

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

STEP 5

ActivityManagerService 調(diào)用 ActivityStarter;

ActivityManagerService.java

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null,
                "startActivityAsUser");
    }

STEP 6

ActivityStarter 調(diào)用 ActivityStackSupervisor;

    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {
        ···
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask, reason);

        ···
    }

    int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask, String reason) {

        ···

        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                container, inTask);

       ···
        return mLastStartActivityResult;
    }

    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
        ···

        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        ···
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
           ···
        }
        ···
    }

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        ···
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ···
            } else {
               ···
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            ···
        }
        ···
    }

STEP 7

ActivityStackSupervisor 調(diào)用 ActivityStack;

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
       ···
        return false;
    }

STEP 8

ActivityStack 回調(diào)到 ActivityStackSupervisor ;

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
       ···
        try {
            ···
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            ···
        }
        ···
        return result;
    }

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
     
        ···
        if (next.app != null && next.app.thread != null) {
           ···
        } else {
            ···
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        ···
    }

STEP 9

ActivityStackSupervisor 回調(diào)到 ActivityManagerService,這里會(huì)判斷要啟動(dòng) App 的進(jìn)程是否存在,存在則通知進(jìn)程啟動(dòng) Activity,否則就先將進(jìn)程創(chuàng)建出來(lái);

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
       ···
        if (app != null && app.thread != null) {
            try {
               ···
                // 如果進(jìn)程已存在,則通知進(jìn)程啟動(dòng)組件
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                ···
            }
        }
        // 否則先將進(jìn)程創(chuàng)建出來(lái)
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

STEP 10

接著我們來(lái)看看進(jìn)程尚未創(chuàng)建的情況,我們看到這里最終調(diào)用的是 Process#start() 來(lái)啟動(dòng)進(jìn)程;

ActivityManagerService.java

    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        ···
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        ···
    }

    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        ···
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                ···
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);
            }
            ···
    }

STEP 11

ActivityManagerService 通過(guò) socket 通信告知 Zygote 進(jìn)程 fork 子進(jìn)程,即 app 進(jìn)程;

STEP 12

進(jìn)程創(chuàng)建后將 ActivityThread 加載進(jìn)去,執(zhí)行 ActivityThread#main() 方法,實(shí)例化 ActivityThread,同時(shí)創(chuàng)建 ApplicationThread,Looper,Hander 對(duì)象,調(diào)用 ActivityThread#attach(false) 方法進(jìn)行 Binder 通信, 接著 Looper 啟動(dòng)循環(huán);

ActivityThread.java

   public static void main(String[] args) {
       ···
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        ···
        Looper.loop();
        ···
    }


    private void attach(boolean system) {
        ···
        if (!system) {
            ···
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ···
        } else {
           ···
        }
        ···
    }

回到 system_server 中,ActivityManagerService#attachApplication(mAppThread) 方法內(nèi)部調(diào)用了 thread#bindApplication()mStackSupervisor#attachApplicationLocked() 這兩個(gè)方法。

STEP 13

其中,thread#bindApplication() 方法調(diào)用了 ActivityThread#sendMessage(H.BIND_APPLICATION, data) 方法,最終走到了 ActivityThread#handleBindApplication(),進(jìn)而創(chuàng)建 Application 對(duì)象,然后調(diào)用 Application#attach(context) 來(lái)綁定 Context ,創(chuàng)建完 Application 對(duì)象后便是調(diào)用 mInstrumentation#callApplicationOnCreate() 執(zhí)行 Application#onCreate() 生命周期;

ActivityManagerService.java

    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            ···
            attachApplicationLocked(thread, callingPid);
            ···
        }
    }

    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
        ···
        try {
            ···
            if (app.instr != null) {
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            }
            ···
        } catch (Exception e) {
            ···
        }
        ···
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                ···
            }
        }
        ···
    }

ActivityThread#ApplicationThread.java

        public final void bindApplication(String processName, ApplicationInfo appInfo,
            ···
            sendMessage(H.BIND_APPLICATION, data);
        }

ActivityThread.java

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        ···
        mH.sendMessage(msg);
    }

我們來(lái)看看這個(gè) mH 的 handleMessage() 方法;

ActivityThread#H.java

        public void handleMessage(Message msg) {
            ···
            switch (msg.what) {
                ···
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                ···
            }
            ···
        }

創(chuàng)建 mInstrumentation 對(duì)象,調(diào)用 data#info#makeApplication 來(lái)創(chuàng)建 Application 對(duì)象;

ActivityThread.java

    private void handleBindApplication(AppBindData data) {
        ···
        try {
            // 創(chuàng)建 Application 實(shí)例
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
            ···
            try {
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ···
            }
        } finally {
            ···
        }
        ···
    }

LoadedApk.java

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
        ···
        Application app = null;
        ···
        try {
            ···
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            ···
        } catch (Exception e) {
            ···
        }
        ···
        if (instrumentation != null) {
            try {
                //執(zhí)行 Application#onCreate() 生命周期
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ···
            }
        }
        ···
        return app;
    }

STEP 14

mStackSupervisor#attachApplicationLocked() 方法中調(diào)用 app#thread#scheduleLaunchActivity()ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法,進(jìn)而通過(guò) ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最終走到了 ActivityThread#handleLaunchActivity() ,進(jìn)而創(chuàng)建 Activity 對(duì)象,然后調(diào)用 activity.attach() 方法,再調(diào)用 mInstrumentation#callActivityOnCreate() 執(zhí)行 Activity#onCreate() 生命周期;

ActivityStackSupervisor.java

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
      
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ···
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                ···
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            ···
                        }
                    }
                }
            }
        }
        ···
    }

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ···
        try {
            ···
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    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, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
             ···
        } catch (RemoteException e) {
            ···
        }
        ···
    }

ActivityThread#ApplicationThread.java

        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
            ···
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

ActivityThread.java

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        ···
        mH.sendMessage(msg);
    }

我們同樣來(lái)看看這個(gè) mH 的 handleMessage() 方法;

ActivityThread#H.java

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    ···
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    ···
                } break;
                ···
            }
            ···
        }

ActivityThread.java

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ···
        Activity a = performLaunchActivity(r, customIntent);
        ···
    }

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ···
        Activity activity = null;
        try {
            //創(chuàng)建 Activity 對(duì)象
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
           ···
        } catch (Exception e) {
            ···
        }

        try {
            ···

            if (activity != null) {
                ···
                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);

                ···
                //執(zhí)行 Activity#onCreate() 生命周期
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ···
            }
            ···
        } catch (SuperNotCalledException e) {
            ···
        } catch (Exception e) {
            ···
    }

到這里,整個(gè) app 啟動(dòng)流程以及源碼調(diào)用皆已分析完畢

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容