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

一、寫在前面

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

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

關(guān)鍵類簡介

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

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


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

二、流程分析

先來一張流程簡圖:


app 啟動流程簡圖

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


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

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


android-boot

三、概述

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

  1. 當(dāng)點(diǎn)擊桌面 App 的時(shí)候,發(fā)起進(jìn)程就是 Launcher 所在的進(jìn)程,啟動遠(yuǎn)程進(jìn)程,利用 Binder 發(fā)送消息給 system_server 進(jìn)程;
  1. 在 system_server 中,啟動進(jìn)程的操作會先調(diào)用
    ActivityManagerService#startProcessLocked() 方法,該方法內(nèi)部調(diào)用 Process.start(android.app.ActivityThread);而后通過 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() 方法會實(shí)例化 ActivityThread,同時(shí)創(chuàng)建 ApplicationThread,Looper,Handler 對象,調(diào)用 ActivityThread#attach(false) 方法進(jìn)行 Binder 通信,方法里面調(diào)用 ActivityManagerService#attachApplication(mAppThread) 方法,將 thread 信息告知 ActivityManagerService , 接著 Looper 啟動循環(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 對象,然后調(diào)用 Application#attach(context) 來綁定 Context ,創(chuàng)建完 Application 對象后便是調(diào)用 mInstrumentation#callApplicationOnCreate() 執(zhí)行 Application#onCreate() 生命周期;
    4.2 mStackSupervisor#attachApplicationLocked() 方法中調(diào)用 app#thread#scheduleLaunchActivity()ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法,進(jìn)而通過 ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最終走到了 ActivityThread#handleLaunchActivity() ,進(jìn)而創(chuàng)建 Activity 對象,然后調(diào)用 activity.attach() 方法,再調(diào)用 mInstrumentation#callActivityOnCreate() 執(zhí)行 Activity#onCreate() 生命周期;

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

對應(yīng)本文第一張流程圖的每一個(gè)步驟,下面逐步來看看源碼是怎么調(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 通過 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,這里會判斷要啟動 App 的進(jìn)程是否存在,存在則通知進(jìn)程啟動 Activity,否則就先將進(jìn)程創(chuàng)建出來;

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

STEP 10

接著我們來看看進(jìn)程尚未創(chuàng)建的情況,我們看到這里最終調(diào)用的是 Process#start() 來啟動進(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 通過 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 對象,調(diào)用 ActivityThread#attach(false) 方法進(jìn)行 Binder 通信, 接著 Looper 啟動循環(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 對象,然后調(diào)用 Application#attach(context) 來綁定 Context ,創(chuàng)建完 Application 對象后便是調(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);
    }

我們來看看這個(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 對象,調(diào)用 data#info#makeApplication 來創(chuàng)建 Application 對象;

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)而通過 ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最終走到了 ActivityThread#handleLaunchActivity() ,進(jìn)而創(chuàng)建 Activity 對象,然后調(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);
    }

我們同樣來看看這個(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 對象
            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 啟動流程以及源碼調(diào)用皆已分析完畢

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,784評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,746評論 2 370

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