Android9.0應用程序啟動過程源碼分析

用戶從Launcher程序點擊應用圖標可啟動應用的入口Activity,Activity啟動時需要多個進程之間的交互,Android系統(tǒng)中有一個zygote進程專用于孵化Android框架層和應用層程序的進程。還有一個system_server進程,該進程里運行了很多binder service,例如ActivityManagerService,PackageManagerService,WindowManagerService,他們分別運行在不同的線程中。

用戶在Launcher程序里點擊應用圖標時,會通知ActivityManagerService啟動應用的入口Activity,ActivityManagerService則會通知Zygote進程孵化出應用進程,然后在這個應用進程里執(zhí)行ActivityThread的main方法。應用進程接下來通過ActivityManagerProxy通知ActivityManagerService應用進程已啟動,ActivityManagerService保存應用進程的一個代理對象ApplicationThreadProxy,這樣ActivityManagerService可以通過ApplicationThreadProxy這個代理對象控制應用進程,然后ActivityManagerService通知應用進程創(chuàng)建入口Activity的實例,并執(zhí)行它的生命周期方法。Android應用程序啟動過程如下圖:


Android應用程序啟動過程.png

應用程序的啟動過程其實就是入口Activity的啟動過程,接下來我們主要分析用戶點擊手機桌面應用程序的圖標到根Activity的onCreate()生命周期方法的執(zhí)行。

啟動過程源碼調(diào)用時序圖

整個 startActivity 的流程分為 3 大部分,也涉及 3 個進程之間的交互:

  • Launcher --> ActivityManagerService
  • ActivityManagerService --> ApplicationThread
  • ApplicationThread --> Activity

詳細分析源代碼的實現(xiàn)過程


友情提示:為了方便閱讀和排版,我所截取的只是framework層部分源碼,保留了源碼的大概框架,目前只關(guān)心Launcher點擊到執(zhí)行Activity的onCreate()生命周期這一條主線,其他代碼用...省略


Launcher --> ActivityManagerService

1、Launcher->startActivitySafely->startActivity

路徑:packages/apps/Launcher2/src/com/android/launcher2/Laucher.java

public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
        View.OnTouchListener {
    
    /**
     * Launches the intent referred by the clicked shortcut.
     *
     * @param v The view representing the clicked shortcut.
     */
    public void onClick(View v) {
        // Make sure that rogue clicks don't get through while allapps is launching, or after the
        // view has detached (it's possible for this to happen if the view is removed mid touch).
        if (v.getWindowToken() == null) {
            return;
        }

        if (!mWorkspace.isFinishedSwitchingState()) {
            return;
        }

        Object tag = v.getTag();
        if (tag instanceof ShortcutInfo) {
            // Open shortcut
            final Intent intent = ((ShortcutInfo) tag).intent;
            int[] pos = new int[2];
            v.getLocationOnScreen(pos);
            intent.setSourceBounds(new Rect(pos[0], pos[1],
                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));

            // ---------看這里---------
            boolean success = startActivitySafely(v, intent, tag);
            ...
        } else if (tag instanceof FolderInfo) {
            ...
        } else if (v == mAllAppsButton) {
            ...
        }
    }

    boolean startActivitySafely(View v, Intent intent, Object tag) {
        boolean success = false;
        try {
            // ---------看這里---------
            success = startActivity(v, intent, tag);
        } catch (ActivityNotFoundException e) {
            ...
        }
        return success;
    }

    boolean startActivity(View v, Intent intent, Object tag) {
        // ---------看這里---------
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        try {
            // Only launch using the new animation if the shortcut has not opted out (this is a
            // private contract between launcher and may be ignored in the future).
            boolean useLaunchAnimation = (v != null) &&
                    !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
            UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);
            LauncherApps launcherApps = (LauncherApps)
                    this.getSystemService(Context.LAUNCHER_APPS_SERVICE);
            if (useLaunchAnimation) {
                ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
                        v.getMeasuredWidth(), v.getMeasuredHeight());
                if (user == null || user.equals(android.os.Process.myUserHandle())) {
                    // Could be launching some bookkeeping activity
                    // ---------看這里---------
                    startActivity(intent, opts.toBundle());
                } else {
                    ...
                }
            } else {
                ...
            }
            return true;
        } catch (SecurityException e) {
            ...
        }
        return false;
    }
}

最后一個startActivity()里面調(diào)用了
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
表示要在一個新的Task(任務(wù)棧)中啟動這個Activity

Android系統(tǒng)中的每一個Activity都位于一個Task中,一個Task可以包含多個Activity,同一個Activity也可能有多個實例。 在AndroidManifest.xml中,我們可以通過android:launchMode來控制Activity在Task中的實例。
在startActivity的時候,我們也可以通過setFlag 來控制啟動的Activity在Task中的實例。

在Task之外,還有一層容器,這個容器應用開發(fā)者和用戶可能都不會感覺到或者用到,但它卻非常重要,那就是Stack,Android系統(tǒng)中的多窗口管理,就是建立在Stack的數(shù)據(jù)結(jié)構(gòu)上的。 一個Stack中包含了多個Task,一個Task中包含了多個Activity(Window)。

2、Activity->startActivity->startActivityForResult

路徑:/frameworks/base/core/java/android/app/Activity.java

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback, WindowControllerCallback,
        AutofillManager.AutofillClient {

    @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 {
            ...
        }
    }
}

Launcher繼承于Activity類,而Activity類實現(xiàn)了startActivity函數(shù),因此,這里就調(diào)用了Activity->startActivity函數(shù),接著調(diào)用Activity->startActivityForResult;

mParent是Activity類型的,表示當前Activity的父類。因為目前根Activity還沒有創(chuàng)建出來,因此,mParent == null 為true,

這里的mInstrumentation是Activity類的成員變量,它的類型是Intrumentation,Intrumentation主要用來監(jiān)控應用程序和系統(tǒng)的交互,后面會講到。

這里的mMainThread也是Activity類的成員變量,它的類型是ActivityThread,ActivityThread 可以理解為一個進程。通過mMainThread.getApplicationThread獲得它里面的ApplicationThread成員變量,它是一個Binder對象,ActivityManagerService會使用它來和ActivityThread來進行進程間通信。要注意的是,這里的mMainThread代表的是Launcher應用程序運行的進程。

3、Instrumentation->execStartActivity

路徑:/frameworks/base/core/java/android/app/Instrumentation.java

Instrumentation 類主要用來監(jiān)控應用程序與系統(tǒng)交互。Instrumentation 中通過 ActivityManger.getService 獲取 AMS 的實例。

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        if (mActivityMonitors != null) {
            ...
        }
        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);
            ...
        } catch (RemoteException e) {
            ...
        }
        return null;
    }

路徑:/frameworks/base/core/java/android/app/ActivityManager.java

ActivityManger類提供與Activity、Service和Process相關(guān)的信息以及交互方法, 可以被看作是ActivityManagerService的輔助類。

 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;
                }
            };

這里的ActivityManager.getService()采用單例,返回的是實現(xiàn)IBinder類型的AMS代理對象,最后將它轉(zhuǎn)換成IActivityManager類型的對象,這段代碼采用的是AIDL,IActivityManager.java類是由AIDL工具在編譯時自動生成的,要實現(xiàn)進程間通信,服務(wù)器端也就是AMS只需要繼承IActivityManager.Stub類并實現(xiàn)相應的方法。所以execStartActivity最終調(diào)用的是AMS的startActivity方法。至此,代碼邏輯進入AMS

ActivityManagerService --> ApplicationThread

這個過程主要就干了 2 件事:

  1. 綜合處理 launchMode 和 Intent 中的 Flag 標志位,并根據(jù)處理結(jié)果生成一個目標 Activity 的對象(ActivityRecord)。
  2. 判斷是否需要為目標 Activity 創(chuàng)建一個新的進程(ProcessRecord)、新的任務(wù)棧(TaskRecord)。
    接下來就從 AMS 的 startActivity 方法開始看起:
4、ActivityManagerService->startActivity

路徑:/frameworks/base/services/core/java/com/android/server/am/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) {
            // ---------看這里---------
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    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,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");

        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        // ---------看這里---------
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

    }

mActivityStartController一系列的鏈式調(diào)用初始化ActivityStarter,最終調(diào)用ActivityStarter的execute()方法

路徑:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

ActivityStarter 這個類看名字就知道它專門負責一個 Activity 的啟動操作。它的主要作用包括解析 Intent、創(chuàng)建 ActivityRecord(Activity實例)、如果有可能還要創(chuàng)建 TaskRecord。

int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                // ---------看這里---------
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            } else {
                // ---------看這里---------
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }
        } finally {
            onExecutionComplete();
        }
    }

startActivityMayWait()里面最后還是會調(diào)用else里面的startActivity(),startActivity()調(diào)用還會調(diào)用ActivityStarter中的兩個另外的startActivity(),最里層的startActivity()源碼如下:

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

       ...

        return result;
    }

接著繼續(xù)調(diào)用ActivityStarter中的startActivityUnchecked()方法

 // Note: This method should only be called from {@link startActivity}.
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        // 初始化ActivityStarter全局變量
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        
        // 計算mLaunchFlags, 一般是判斷是否需要在mLaunchFlags中加入FLAG_ACTIVITY_NEW_TASK
        computeLaunchingTaskFlags();

        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);
        ...
        // 判斷是否應將新Activity插入到現(xiàn)有任務(wù)棧中
        // 如果不需要,則返回null,如果需要,則返回該任務(wù)棧信息
        ActivityRecord reusedActivity = getReusableIntentActivity();
        if (reusedActivity != null) {

            if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
                    (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
                Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }

            ...

            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
                    || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
                final TaskRecord task = reusedActivity.getTask();
                ...
            }

            mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);

            reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);

            final ActivityRecord outResult =
                    outActivity != null && outActivity.length > 0 ? outActivity[0] : null;

            if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
                outActivity[0] = reusedActivity;
            }

            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                resumeTargetStackIfNeeded();
                return START_RETURN_INTENT_TO_CALLER;
            }
        }

        if (mStartActivity.packageName == null) {
            ...
            return START_CLASS_NOT_FOUND;
        }

        // If the activity being launched is the same as the one currently at the top, then
        ...
        
        if (dontStart) {
            ...
            return START_DELIVERED_TO_TOP;
        }

        ...
                
        // 使新Activity可見
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                mService.mWindowManager.executeAppTransition();
            } else {
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                // ---------看這里---------
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else if (mStartActivity != null) {
            ...
        }
       ...

        return START_SUCCESS;
    }

startActivityUnchecked方法最重要的工作就是為待啟動的ActivityRecord找到他對應的TaskRecord和ActivityStack

5、ActivityStackSupervisor->resumeFocusedStackTopActivityLocked

路徑:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        if (!readyToResume()) {
            return false;
        }

        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        // 獲取要啟動的Activity所在棧的棧頂?shù)牟皇浅鲇谕V範顟B(tài)的ActivityRecord
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || !r.isState(RESUMED)) {
            // ---------看這里---------
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.isState(RESUMED)) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }

        return false;
    }

mFocusedStack是ActivityStackSupervisor的一個成員變量,類型是ActivityStack
如果獲取的ActivityRecord不為null,或者要啟動的Activity的狀態(tài)不是RESUMED,則會調(diào)用ActivityStack的resumeTopActivityUncheckedLocked方法。繼續(xù)跟進resumeTopActivityUncheckedLocked方法。

6、ActivityStack->resumeFocusedStackTopActivityLocked

路徑:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

@GuardedBy("mService")
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            
            // ---------看這里---------
            result = resumeTopActivityInnerLocked(prev, options);

            // When resuming the top activity, it may be necessary to pause the top activity (for
            // example, returning to the lock screen. We suppress the normal pause logic in
            // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
            // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
            // to ensure any necessary pause logic occurs. In the case where the Activity will be
            // shown regardless of the lock screen, the call to
            // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }

        return result;
    }

接著調(diào)用resumeTopActivityInnerLocked方法,繼續(xù)跟進

@GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...
        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {
            
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwich */);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            // ---------看這里---------
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

這里又回到了ActivityStackSupervisor中的startSpecificActivityLocked方法

7、ActivityStackSupervisor->startSpecificActivityLocked

路徑:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // 獲取即將啟動的Activiy所在的應用程序進程
        // 處根據(jù)進程名稱和 Application 的 uid 來判斷目標進程是否已經(jīng)創(chuàng)建,如果沒有則代表進程未創(chuàng)建。
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        getLaunchTimeTracker().setLaunchTime(r);

        if (app != null && app.thread != null) {// Activity所在的應用程序已經(jīng)運行
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                            mService.mProcessStats);
                }
                // ---------看這里---------
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

        }

        // 調(diào)用 AMS 創(chuàng)建 Activity 所在進程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

realStartActivityLocked 方法來執(zhí)行啟動 Activity 的操作。跟進realStartActivityLocked方法

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ...           

            try {
                ...

                // 這里傳入的app.thread會賦值給ClientTransaction的成員變量mClient,
                // 而ClientTransaction會調(diào)用mClient.scheduleTransaction(this)來執(zhí)行事務(wù)
                // 所以事務(wù)最終是調(diào)用app.thread的scheduleTransaction執(zhí)行。
                // 而這個app.thread是ActivityThread的內(nèi)部類ApplicationThread。
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                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, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                // ---------看這里---------
                // 執(zhí)行Activity啟動事務(wù)
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                ...
            } catch (RemoteException e) {
                if (r.launchFailed) {
                    // 第二次啟動失敗的異常處理
                    return false;
                }

                // 第一次啟動失敗,重試
                r.launchFailed = true;
                app.activities.remove(r);
                throw e;
            }
        } finally {
            endDeferResume();
        }
        ...
        return true;
    }

這個方法在 android-27 和 android-28 版本的區(qū)別很大,從 android-28 開始 Activity 的啟動交給了事務(wù)(Transaction)來完成。在realStartActivityLocked中最主要的工作就是創(chuàng)建了Activity的啟動事務(wù)ClientTransaction,并調(diào)用ClientLifecycleManager的scheduleTransaction方法啟動它。接下來,看ClientTransaction事務(wù)中是怎么啟動Activity的。

路徑:/frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        
        // ---------看這里---------
        transaction.schedule();
        
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

調(diào)用ClientTransaction的schedule方法,而這個 transaction 實際上是在創(chuàng)建 ClientTransaction 時傳入的 app.thread 對象,也就是 ApplicationThread。繼續(xù)跟進

    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

這里調(diào)用了mClient的scheduleTransaction方法,這里的mClient是在創(chuàng)建ClientTransaction事務(wù)對象的時候賦值的,也就是調(diào)用obtain方法時。

路徑:/frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java

    public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
        ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
        if (instance == null) {
            instance = new ClientTransaction();
        }
        instance.mClient = client;
        instance.mActivityToken = activityToken;

        return instance;
    }

好,回到ActivityStackSupervisor的realStartActivityLocked方法中,最終會調(diào)用mService.getLifecycleManager().scheduleTransaction(clientTransaction)啟動Activity事務(wù),可以看到,獲取clientTransaction參數(shù)的obtain方法中,賦值給mClient的是app.thread,所以事務(wù)最終是調(diào)用的app.thread的scheduleTransaction方法來執(zhí)行,而這個app.thread是ActivityThread的內(nèi)部類ApplicationThread。所以流程轉(zhuǎn)到了ActivityThread的內(nèi)部類ApplicationThread中。

ApplicationThread --> Activity

8、ActivityThread.ApplicationThread->scheduleTransaction

路徑:/frameworks/base/core/java/android/app/ActivityThread.java

    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }

這里還是調(diào)用了ActivityThread的scheduleTransaction方法。但是ActivityThread類中并沒有scheduleTransaction這個方法。因此自然會想到很可能是繼承的父類中的方法。ActivityThread繼承的是ClientTransactionHandler類,在ClientTransactionHandler類中發(fā)現(xiàn)了scheduleTransaction方法。所以這里最終調(diào)用的就是ClientTransactionHandler中的scheduleTransaction方法。

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

調(diào)用 sendMessage 方法,向 Handler 中發(fā)送了一個 EXECUTE_TRANSACTION 的消息,并且 Message 中的 obj 就是啟動 Activity 的事務(wù)對象。sendMessage是一個抽象方法,所以這里調(diào)用的是ActivityThread類中的sendMessage實現(xiàn)。

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        // ---------看這里---------
        mH.sendMessage(msg);
    }

這里就是生成了一個Message對象,并向mH這個Handler發(fā)送一個what為ActivityThread.H.EXECUTE_TRANSACTION的消息。去查看Handler(ActivityThread.H)中對EXECUTE_TRANSACTION消息的處理。

case EXECUTE_TRANSACTION:
        final ClientTransaction transaction = (ClientTransaction) msg.obj;
        // ---------看這里---------
        // 調(diào)用TransactionExecutor的execute方法
        mTransactionExecutor.execute(transaction);
        if (isSystem()) {
            // Client transactions inside system process are recycled on the client side
            // instead of ClientLifecycleManager to avoid being cleared before this
            // message is handled.
            transaction.recycle();
        }
        // TODO(lifecycler): Recycle locally scheduled transactions.
        break;
9、TransactionExecutor->execute

路徑:/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor
這里調(diào)用了TransactionExecutor的execute方法

    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        // ---------看這里---------
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        
        mPendingActions.clear();
        log("End resolving transaction");
    }

這里調(diào)用了executeCallbacks和executeLifecycleState兩個方法,查看兩個方法就會發(fā)現(xiàn),這兩個方法最后都會調(diào)用cycleToPath這個方法。

    private void cycleToPath(ActivityClientRecord r, int finish,
            boolean excludeLastState) {
        final int start = r.getLifecycleState();
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        // ---------看這里---------
        performLifecycleSequence(r, path);
    }

繼續(xù)看performLifecycleSequence方法

    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            log("Transitioning to state: " + state);
            switch (state) {
                case ON_CREATE:
                 // ---------看這里---------
                 mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r.token, false /* show */,
                            0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r.token, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

可以看到,Activity的生命周期就是在這里進行一個相關(guān)方法的調(diào)用。
這里的成員變量mTransactionHandler是一個ClientTransactionHandler對象,在ClientTransactionHandler中這些方法都是抽象方法,這里執(zhí)行的是ClientTransactionHandler的實現(xiàn)類ActivityThread中的handleLaunchActivity方法。

10、ActivityThread->handleLaunchActivity

路徑:/frameworks/base/core/java/android/app/ActivityThread.java

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);

        // Initialize before creating the activity
        if (!ThreadedRenderer.sRendererDisabled) {
            GraphicsEnvironment.earlyInitEGL();
        }
        //創(chuàng)建WindowManagerServer
        WindowManagerGlobal.initialize();

        // ---------看這里---------
        // 通過反射創(chuàng)建指定的Activity,并回調(diào)Activity的performCreate方法執(zhí)行onCreate
        final Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            if (!r.activity.mFinished && pendingActions != null) {
                pendingActions.setOldState(r.state);
                pendingActions.setRestoreInstanceState(true);
                pendingActions.setCallOnPostCreate(true);
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        return a;
    }

好,繼續(xù)跟進performLaunchActivity方法

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // 獲取ActivityInfo類
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            // 獲取APK文件描述的LoadedAPK
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        // 獲取要啟動的Activity的ComponentName類,該類保存了Activity類名和包名
        ComponentName component = r.intent.getComponent();
        ...

        // 創(chuàng)建要啟動Activity的上下文環(huán)境
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // 用類加載器來創(chuàng)建Activity實例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } catch (Exception e) {
            ...
        }

        try {
            // 創(chuàng)建Application,makeApplication方法內(nèi)部會調(diào)用創(chuàng)建Application的onCreate()
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                ...
                // 初始化Activity,在attach方法中會創(chuàng)建window對象并與Activity關(guān)聯(lián)
                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);
                ...

                if (r.isPersistable()) {
                    // ---------看這里---------
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
               ...
            }
            ...
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            ...
        }

        return activity;
    }

這個方法中的注釋已經(jīng)很明確了,獲取ActivityInfo、ComponentName、appContext,并創(chuàng)建了Application,回調(diào)Application的onCreate(),最后調(diào)用Instrumentation的callActivityOnCreate()方法來啟動Activity

11、Instrumentation->callActivityOnCreate

路徑:/frameworks/base/core/java/android/app/Instrumentation.java

public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        // ---------看這里---------
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

可以看到,最終是調(diào)用了Activity的performCreate()方法,繼續(xù)跟進

12、Activity->performCreate

路徑:/frameworks/base/core/java/android/app/Activity.java

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            // ---------看這里---------
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
        mActivityTransitionState.readState(icicle);

        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchActivityCreated();
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    }

到目前為止,我們分析了Launcher請求AMS、AMS到ApplicationThread的調(diào)用過程、ActivityThread啟動Activity的過程,從根Activity的啟動過程中可以看到,若我們想做啟動耗時優(yōu)化,目前最明顯且易控制的方式就是盡量少在Application和Activity的onCreate()方法中做耗時操作,一些后面才會用到的庫或者其他三方庫可以延遲初始化。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容