AMS之Activity启动(AndroidV)

一:背景

    Activity作为Android四大组件之一,用途之广、作用之重要想必不需要多做赘述,下面将从Launcher点击Dialer图标这个流程来剖析Activity是如何启动的。

PS:点击事件在Launcher中的传递本篇文章不涉及,流程起始点是ContextImpl.startActivity

二:Activity启动流程

    2.1 准备工作

    2.1.1 ContextImpl.startActivity

      最终会通过ActivityTaskManagerService调用到ActivityStarter,在ActivityStarter中做真正Activity启动工作。

//frameworks/base/core/java/android/app/ContextImpl.java
    public void startActivity(Intent intent) {
        warnIfCallingFromSystemProcess();
        startActivity(intent, null);
    }

//frameworks/base/core/java/android/app/ContextImpl.java
    public void startActivity(Intent intent, Bundle options) {
        ...
        mMainThread.getInstrumentation().execStartActivity(
                getOuterContext(), mMainThread.getApplicationThread(), null,
                (Activity) null, intent, -1, options);
    }

//frameworks/base/core/java/android/app/Instrumentation.java
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            //启动Activity
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getOpPackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            notifyStartActivityResult(result, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    public final int startActivity(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        ...
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(opts)
                .setUserId(userId)
                .execute();
    }

2.1.2 ActivityStarter.execute

  这里主要完成以下工作

  • 校验Activity启动合法性,判断是否需要拦截Activity启动
  • 创建ActivityRecord对象
  • 校准Activity启动的flag,并根据flag判断是否有可以复用的task,没有则创建新的任务栈
  • 计算Activity的参数,如窗口区域、窗口模式等
  • 开始播放Activity启动时startingWindow动画
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
    int execute() {
        try {
            //执行开始即开始启动Activity
            onExecutionStarted();
            ...
            int res = START_CANCELED;
            synchronized (mService.mGlobalLock) {
                ...
                try {
                    ...
                    res = executeRequest(mRequest);
                } finally {
                    ...
                }
                ...
            }
            ...
        } finally {
            //执行结束即Activity启动结束
            onExecutionComplete();
        }
    ...
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
    private int executeRequest(Request request) {
        ...
        //判断是否需要拦截Activity启动
        if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
                callingPid, callingUid, checkedOptions, suggestedLaunchDisplayArea)) {
            ...
            intentGrants = null;
        }
        ...
        //创建ActivityRecord对象
        final ActivityRecord r = new ActivityRecord.Builder(mService)
                ...
                .build();
        ...
        //启动Activity
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, checkedOptions,
                inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid);
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment,
            BalVerdict balVerdict,
            NeededUriGrants intentGrants, int realCallingUid) {
        ...
        try {
            mService.deferWindowLayout();
            transitionController.collect(r);
            try {
                //开始"startActivityInner" trace的地方
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
                //启动Activity
                result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, options, inTask, inTaskFragment, balVerdict,
                        intentGrants, realCallingUid);
            } catch (Exception ex) {
                Slog.e(TAG, "Exception on startActivityInner", ex);
            } finally {
                //结束"startActivityInner" trace的地方
                Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
                startedActivityRootTask = handleStartResult(r, options, result, newTransition,
                        remoteTransition);
            }
        } finally {
            mService.continueWindowLayout();
        }
        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }

//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, BalVerdict balVerdict,
            NeededUriGrants intentGrants, int realCallingUid) {
        //初始化状态
        setInitialState(r, options, inTask, inTaskFragment, startFlags, sourceRecord,
                voiceSession, voiceInteractor, balVerdict.getCode(), realCallingUid);
        //校准mLaunchFlags并更新到mIntent中
        computeLaunchingTaskFlags();
        mIntent.setFlags(mLaunchFlags);
        ...
        //根据includeLaunchedFromBubble判断是否有task可以复用,并返回可以复用的task
        final Task reusedTask = resolveReusableTask(includeLaunchedFromBubble);
        ...
        //判断是否有可以使用的现成的task(例如在应用中通过Activity1启动Activity2,启动方式是standard,那么Activity1所在的task就可以给Activity2使用而不需要重新创建一个task)
        final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
        final boolean newTask = targetTask == null;
        ...
        //计算启动Activity时的参数,例如窗口区域、窗口模式等
        computeLaunchParams(r, sourceRecord, targetTask);
        //检查启动是否被允许
        int startResult = isAllowedToStart(r, newTask, targetTask);

        ...

        final ActivityRecord targetTaskTop = newTask
                ? null : targetTask.getTopNonFinishingActivity();
        if (targetTaskTop != null) {
            //Activity的启动模式是SINGLE_INSTANCE,移除所有有该Activity的任务栈
            if (LAUNCH_SINGLE_INSTANCE == mLaunchMode && mSourceRecord != null
                    && targetTask == mSourceRecord.getTask()) {
                final ActivityRecord activity = mRootWindowContainer.findActivity(mIntent,
                        mStartActivity.info, false);
                if (activity != null && activity.getTask() != targetTask) {
                    activity.destroyIfPossible("Removes redundant singleInstance");
                }
            }
            ...
        }
        //如果当前任务栈的最上层Activity是将要启动的Activity,判断是否需要再次启动Activity(standard模式会再次启动,singletop模式则不会再次启动)
        final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
        if (topRootTask != null) {
            startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
            if (startResult != START_SUCCESS) {
                return startResult;
            }
        }
        ...
        //可用任务栈不存在,创建新的任务栈
        if (mTargetRootTask == null) {
            mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
                    mOptions);
        }
        ...
        //在event log中记录有新的task创建了
        if (newTask) {
            EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId,
                    startedTask.getRootTaskId(), startedTask.getDisplayId());
        }
        //在event log中记录create Activity
        mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);
        ...
        //开始Activity启动过渡动画
        mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
                mOptions, sourceRecord);
        //mDoResume为true
        if (mDoResume) {
            final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
            if (!mTargetRootTask.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && mStartActivity != topTaskActivity)) {
                ...
                mTargetRootTask.ensureActivitiesVisible(null /* starting */);
                mTargetRootTask.mDisplayContent.executeAppTransition();
            } else {
                ...
                mRootWindowContainer.resumeFocusedTasksTopActivities(
                        mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
            }
        }
        ...
        //更新最近任务栈
        mSupervisor.mRecentTasks.add(startedTask);
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/Task.java
    void startActivityLocked(ActivityRecord r, @Nullable Task topTask, boolean newTask,
            boolean isTaskSwitch, ActivityOptions options, @Nullable ActivityRecord sourceRecord) {
        ...
        final DisplayContent dc = mDisplayContent;
        if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {//不需要过渡动画
            ...
        } else {
            //准备过渡动画
            dc.prepareAppTransition(TRANSIT_OPEN);
            mTaskSupervisor.mNoAnimActivities.remove(r);
        }
        ...
        //后台启动
        if (r.mLaunchTaskBehind) {
            ...
        } else if (SHOW_APP_STARTING_PREVIEW && doShow) {//SHOW_APP_STARTING_PREVIEW为true
            ...
            //开始StartingWindow动画
            mWmService.mStartingSurfaceController.showStartingWindow(r, prev, newTask,
                    isTaskSwitch, sourceRecord);
        }
    }

//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
    boolean resumeFocusedTasksTopActivities(
            Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
            boolean deferPause) {
        ...
        if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                || getTopDisplayFocusedRootTask() == targetRootTask)) {
            result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                    deferPause);
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/Task.java
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ...
        try {
            ...
            if (isLeafTask()) {
                if (isFocusableAndVisible()) {
                    someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
                }
            }
            ...
        }
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/Task.java
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ...
        final boolean[] resumed = new boolean[1];
        final TaskFragment topFragment = topActivity.getTaskFragment();
        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
        forAllLeafTaskFragments(f -> {
            if (topFragment == f) {
                return;
            }
            if (!f.canBeResumed(null /* starting */)) {
                return;
            }
            resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
        }, true);
        return resumed[0];
    }

//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean skipPause) {
        ...
        //暂停前一个Activity
        boolean pausing = !skipPause && taskDisplayArea.pauseBackTasks(next);
        ...
        if (pausing) {
            ...
            if (next.attachedToProcess()) {//Activity所属进程已存在
                ...
            } else if (!next.isProcessRunning()) {//Activity所属进程不存在
                ...
                //启动Activity所属进程
                mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                        isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
                                : HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
            }
            ...
        }
        ...
        boolean anim = true;
        final DisplayContent dc = taskDisplayArea.mDisplayContent;
        if (prev != null) {
            if (prev.finishing) {
                ...
                if (mTaskSupervisor.mNoAnimActivities.contains(prev)) {
                    ...
                } else {
                    //过渡动画准备完成
                    dc.prepareAppTransition(TRANSIT_CLOSE);
                }
                prev.setVisibility(false);
            } else {
                ...
            }
        } else {
            ...
        }

        if (anim) {
            //播放过渡动画
            next.applyOptionsAnimation();
        } else {
            ...
        }
        ...
        if (next.attachedToProcess()) {
            ...
            //更新CPU统计信息
            mAtmService.updateCpuStats();
            //更新状态
            next.setState(RESUMED, "resumeTopActivity");
            ...
            try {
                ...
                //标记Activity resume
                next.notifyAppResumed();
            ...
    }

2.2 暂停前一个Activity

2.2.1 TaskFragment.startPausing

  获取需要暂停的ActivityRecord(即当前处于resume状态的Activity对应的ActivityRecord),更新需要暂停Activity的状态为PAUSING,调用TaskFragment的schedulePauseActivity做真正暂停Activity的工作

//frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
    boolean pauseBackTasks(ActivityRecord resuming) {
        final int[] someActivityPaused = {0};
        forAllLeafTasks(leafTask -> {
            //调用Task的pauseActivityIfNeeded来暂定Activity,暂停原因是"pauseBackTasks"
            if (leafTask.pauseActivityIfNeeded(resuming, "pauseBackTasks")) {
                someActivityPaused[0]++;
            }
        }, true /* traverseTopToBottom */);
        return someActivityPaused[0] > 0;
    }

//frameworks/base/services/core/java/com/android/server/wm/Task.java
    boolean pauseActivityIfNeeded(@Nullable ActivityRecord resuming, @NonNull String reason) {
        ...
        forAllLeafTaskFragments((taskFrag) -> {
            final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
            if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
                //调用TaskFragment的startPausing继续暂停流程
                if (taskFrag.startPausing(false /* uiSleeping*/, resuming, reason)) {
                    someActivityPaused[0]++;
                }
            }
        }, true /* traverseTopToBottom */);
        ...
    }

//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
            String reason) {
        ...
        //将要暂停的Activity对应的ActivityRecord赋值给prev
        ActivityRecord prev = mResumedActivity;
        ...
        mPausingActivity = prev;
        ...
        //更新状态为PAUSING
        prev.setState(PAUSING, "startPausingLocked");
        prev.getTask().touchActiveTime();
        ...
        if (prev.attachedToProcess()) {
            if (shouldAutoPip && ActivityTaskManagerService.isPip2ExperimentEnabled()) {//画中画模式,不暂停Activity
                ...
            } else if (shouldAutoPip) {//画中画模式,不暂停Activity
                ...
            } else {
                //真正暂停Activity的地方
                schedulePauseActivity(prev, userLeaving, pauseImmediately,
                        false /* autoEnteringPip */, reason);
            }
        }
        ...
        if (mPausingActivity != null) {
            ...
            if (pauseImmediately) {
                //暂停完成
                completePause(false, resuming);
                return false;

            } else {
                ...
            }

        }
        ...
    }

2.2.2 ActivityThread.performPauseActivity

  Activity的暂停是通过PauseActivityItem(Activity 的暂停transaction)来实现。PauseActivityItem会调用ActivityThread,更新Activity的状态为ON_PAUSE,最终通过Activity的performPause来调用到Launcher Activity的onPause函数

//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
            boolean pauseImmediately, boolean autoEnteringPip, String reason) {
        try {
            ...
            //暂停Activity
### Android 应用程序启动流程详解 #### 启动请求发起 当用户点击应用图标或其他方式触发应用启动时,`startActivity()` 方法被调用。此方法负责构建意图(Intent),并通过Intent传递给系统服务层,向 `ActivityManagerService (AMS)` 发送启动Activity 的请求[^3]。 #### 请求处理与准备阶段 AMS 收到启动请求后,解析 Intent 中携带的信息,确定要启动的目标组件及其属性,如启动模式等。接着 AMS 进行一系列准备工作,包括但不限于: - 如果当前有其他 Activity 正处于前台展示,则先让其执行 `onPause()` 操作; - 判断目标 Activity 所属的应用进程是否已存在;如果不存在则创建新的进程实例,并等待该进程中 Application 对象初始化完毕。 #### 创建并显示Activity 一旦上述条件满足,AMS 将指示相应进程内的客户端(通常是应用程序的主线程)通过 `realStartActivity()` 函数继续后续工作。具体来说,在客户端内部会发生如下事件序列: 1. 调用 `scheduleLaunchActivity()` 方法将 LAUNCH_ACTIVITY 消息放入消息队列中。 2. 当轮询到这条消息时,由 `handleLaunchActivity()` 处理它。 3. 接着调用了 `performLaunchActivity()` 来真正地创建一个新的 Activity 实例,并依次回调它的 `onCreate()`, `onStart()` 生命周期函数。 4. 最终再经由 `handleResumeActivity()` 去触发展示前最后一个重要的生命周期钩子——`onResume()`,此时 Activity 已完全就绪可与用户互动[^2]。 ```java // 示例代码片段展示了部分关键逻辑 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 设置UI布局文件 // 初始化操作... } @Override protected void onStart(){ super.onStart(); // 让Activity变得可见... } @Override public void onResume(){ super.onResume(); // 开始接收用户的输入... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值