美文网首页
Android 12系统源码_AMS(一)Activity启动流

Android 12系统源码_AMS(一)Activity启动流

作者: AFinalStone | 来源:发表于2022-12-06 16:20 被阅读0次

    前言

    Android10之前,在系统刚刚启动之后,SystemServer进程的startBootstrapServices方法会启动系统引导服务,像我们常接触的ActivityManagerService、PowerManagerService、PackageManagerService等都是在这里启动的,早期Activity的startActivity方法都是通过Instrumentation和ActivityManagerService做交互,但是随着AMS的职责越来越多、代码越来越庞大,在Android10以后,Google又对AMS做了进一步拆分,最终拆出来一个新的对象ActivityTaskManagerService,用来管理 Activity及其容器类,比如 Task、Stack、Display 等,以分担AMS的部分职责。

    一、Activity触发ATMS执行startActivity方法的过程

    1、时序图


    image.png

    2、Activity的startActivity方法如下所示:

    frameworks/base/core/java/android/app/Activity.java

    public class Activity extends ContextThemeWrapper
            implements LayoutInflater.Factory2,
            Window.Callback, KeyEvent.Callback,
            OnCreateContextMenuListener, ComponentCallbacks2,
            Window.OnWindowDismissedCallback,
            AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
    
        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);
            }
        }
    
    

    startActivity方法会继续调用startActivity(Intent intent, Bundle options),最终会继续调用startActivityForResult方法。

        public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
            startActivityForResult(intent, requestCode, null);
        }
        public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
                  ...代码省略...
                  Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
                ...代码省略...
        }
    

    startActivityForResult方法会调用Instrumentation的execStartActivity方法。

    3、Instrumentation 负责调用 Activity 和 Application 的生命周期,每个 Activity 都持有 Instrumentation 对象的一个引用,但是整个进程只会存在一个 Instrumentation 对象,Instrumentation的execStartActivity方法如下所示:

    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) {
            IApplicationThread whoThread = (IApplicationThread) contextThread;
            ...代码省略...
            try {
                intent.migrateExtraStreamToClipData(who);
                intent.prepareToLeaveProcess(who);
                // 获取 ActivityTaskManagerService 的代理对象
                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);
                checkStartActivityResult(result, intent);
            } catch (RemoteException e) {
                throw new RuntimeException("Failure from system", e);
            }
            return null;
        }
    

    Instrumentation的execStartActivity方法会调用 ActivityTaskManager的getService方法会返回一个IActivityTaskManager类型的实例对象并调用该对象的startActivity方法。

    4、在Android12源码中并不存在IActivityTaskManager.java这样一个文件,只能找到 IActivityTaskManager.aidl文件:

    frameworks/base/core/java/android/app/IActivityTaskManager.aidl

    interface IActivityManager {
        int startActivity(in IApplicationThread caller, in String callingPackage,
                in String callingFeatureId, in Intent intent, in String resolvedType,
                in IBinder resultTo, in String resultWho, int requestCode,
                int flags, in ProfilerInfo profilerInfo, in Bundle options);
    }
    

    我们知道源码编译的时候会将aidl文件转化为 java 文件,IActivityTaskManager的startActivity方法的调用最终是通过binder来实现跨进程通信的。而IActivityTaskManager.aidl中startActivity方法的具体实现类,其实是ActivityTaskManagerService。

    5、ActivityTaskManagerService的startActivity方法如下所示:

    frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

    public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    
        @Override
        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());
        }
    
    }
    

    二、ATMS向AMS 发送创建应用进程的过程

    1、时序图和Activity任务栈

    image.png

    2、ActivityTaskManagerService的startActivity方法会进一步调用startActivityAsUser方法:

    public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    
        private ActivityStartController mActivityStartController;
    
        @Override
        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());
        }
    
        @Override
        public int startActivityAsUser(IApplicationThread caller, String callingPackage,
                String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
                String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
                Bundle bOptions, int userId) {
            return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                    true /*validateIncomingUser*/);
        }
    
        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) {
            // 检查调用者的进程是否隔离,如果 isIsolated 则抛出 SecurityException 异常
            assertPackageMatchesCallingUid(callingPackage);
            // 检查调用者权限,ATMS 根据传入的 UserId 来确定调用者的权限
            enforceNotIsolatedCaller("startActivityAsUser");
    
            userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                    Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    
            return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                    .setCaller(caller)
                    .setCallingPackage(callingPackage)
                    .setCallingFeatureId(callingFeatureId)
                    .setResolvedType(resolvedType)
                    .setResultTo(resultTo)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setStartFlags(startFlags)
                    .setProfilerInfo(profilerInfo)
                    .setActivityOptions(bOptions)
                    .setUserId(userId)
                    .execute();
        }
    
        ActivityStartController getActivityStartController() {
            return mActivityStartController;
        }
    }
    

    3、startActivityAsUser方法最终会调用ActivityStartController的obtainStarter方法获取ActivityStarter对象实例:

    frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

    public class ActivityStartController {
        ActivityStarter obtainStarter(Intent intent, String reason) {
            return mFactory.obtain().setIntent(intent).setReason(reason);
        }
    }
    

    4、获取ActivityStarter对象之后会调用该对象的的setCaller、setCallingPackage等一系列方法进行参数设置,最后调用execute方法,相关方法的代码如下所示:

    class ActivityStarter {
        //内部静态类
        static class Request {
    
            private static final int DEFAULT_CALLING_UID = -1;
            private static final int DEFAULT_CALLING_PID = 0;
            static final int DEFAULT_REAL_CALLING_UID = -1;
            static final int DEFAULT_REAL_CALLING_PID = 0;
    
            IApplicationThread caller;
            Intent intent;
            NeededUriGrants intentGrants;
            // A copy of the original requested intent, in case for ephemeral app launch.
            Intent ephemeralIntent;
            String resolvedType;
            ActivityInfo activityInfo;
            ResolveInfo resolveInfo;
            IVoiceInteractionSession voiceSession;
            IVoiceInteractor voiceInteractor;
            IBinder resultTo;
            String resultWho;
            int requestCode;
            int callingPid = DEFAULT_CALLING_PID;
            int callingUid = DEFAULT_CALLING_UID;
            String callingPackage;
            @Nullable String callingFeatureId;
            int realCallingPid = DEFAULT_REAL_CALLING_PID;
            int realCallingUid = DEFAULT_REAL_CALLING_UID;
            int startFlags;
            SafeActivityOptions activityOptions;
            boolean ignoreTargetSecurity;
            boolean componentSpecified;
            boolean avoidMoveToFront;
            ActivityRecord[] outActivity;
            Task inTask;
            TaskFragment inTaskFragment;
            String reason;
            ProfilerInfo profilerInfo;
            Configuration globalConfig;
            int userId;
            WaitResult waitResult;
            int filterCallingUid;
            PendingIntentRecord originatingPendingIntent;
            boolean allowBackgroundActivityStart;
    
            boolean allowPendingRemoteAnimationRegistryLookup;
    
            Request() {
                reset();
            }
            //为内部设置各种初始化参数
            void reset() {
                caller = null;
                intent = null;
                ...代码省略...
            }
            //更新参数
            void set(@NonNull Request request) {
                caller = request.caller;
                intent = request.intent;
                ...代码省略...
            }
      }
    
        private final RootWindowContainer mRootWindowContainer;
        Request mRequest = new Request();
    
        ActivityStarter setCaller(IApplicationThread caller) {
            mRequest.caller = caller;
            return this;
        }
    
         ActivityStarter setCallingPackage(String callingPackage) {
            mRequest.callingPackage = callingPackage;
            return this;
        }
    
        int execute() {
            try {
                  ...代码省略...
                  final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
                  if (rootTask != null) {
                      rootTask.mConfigWillChange = globalConfigWillChange;
                  }
                  ...代码省略...
                  res = executeRequest(mRequest);  //执行请求操作
                  ...代码省略...
            } finally {
                onExecutionComplete();
            }
        }
    
    }
    

    这里省略了execute的大部分代码,只保留了关键的一步,调用executeRequest方法:

     private int executeRequest(Request request) {
            ...代码省略...
            final ActivityRecord r = new ActivityRecord.Builder(mService)
                    .setCaller(callerApp)
                    .setLaunchedFromPid(callingPid)
                    .setLaunchedFromUid(callingUid)
                    .setLaunchedFromPackage(callingPackage)
                    .setLaunchedFromFeature(callingFeatureId)
                    .setIntent(intent)
                    .setResolvedType(resolvedType)
                    .setActivityInfo(aInfo)
                    .setConfiguration(mService.getGlobalConfiguration())
                    .setResultTo(resultRecord)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setComponentSpecified(request.componentSpecified)
                    .setRootVoiceInteraction(voiceSession != null)
                    .setActivityOptions(checkedOptions)
                    .setSourceRecord(sourceRecord)
                    .build();
    
            ...代码省略...
    
            mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                    request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
                    inTask, inTaskFragment, restrictedBgActivity, intentGrants);
    
            if (request.outActivity != null) {
                request.outActivity[0] = mLastStartActivityRecord;
            }
    
            return mLastStartActivityResult;
        }
    

    executeRequest方法会先将上面获取的相关参数封装成ActivityRecord对象,该对象内部记录了Activity的所有信息,然后会调用startActivityUnchecked方法:

        private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                TaskFragment inTaskFragment, boolean restrictedBgActivity,
                NeededUriGrants intentGrants) {
            ...代码省略...
            try {
                mService.deferWindowLayout();
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
                result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
                        intentGrants);
                ...代码省略...
            } finally {
                  ...代码省略...
                }
            }
            postStartActivityProcessing(r, result, startedActivityRootTask);
            return result;
        }
    

    startActivityUnchecked方法会进一步调用startActivityInner方法:

        int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                TaskFragment inTaskFragment, boolean restrictedBgActivity,
                NeededUriGrants intentGrants) {
            ...代码省略...
           // 因为可能会复用已经存在的页面栈而导致栈顺序发生变化,这里要获取顶部的页面栈
            final Task prevTopTask = mPreferredTaskDisplayArea.getFocusedRootTask();
            final Task reusedTask = getReusableTask();
            ...代码省略...
    
            if (mDoResume) {
                final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
                if (!mTargetRootTask.isTopActivityFocusable()
                        || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                        && mStartActivity != topTaskActivity)) {
                    mTargetRootTask.ensureActivitiesVisible(null /* starting */,
                            0 /* configChanges */, !PRESERVE_WINDOWS);
                    mTargetRootTask.mDisplayContent.executeAppTransition();
                } else {
                    if (mTargetRootTask.isTopActivityFocusable()
                            && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
                        mTargetRootTask.moveToFront("startActivityInner");
                    }
                    //调用RootWindowContainer的resumeFocusedTasksTopActivities方法
                    mRootWindowContainer.resumeFocusedTasksTopActivities(
                            mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
                }
            }
            mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
            // Update the recent tasks list immediately when the activity starts
            mSupervisor.mRecentTasks.add(startedTask);
            mSupervisor.handleNonResizableTaskIfNeeded(startedTask,
                    mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
    
            return START_SUCCESS;
        }
    

    主要就是处理 Activity 的启动模式有关的逻辑,处理已经存在的任务栈,最后会调用RootWindowContainer的resumeFocusedTasksTopActivities方法。

    5、RootWindowContainer是窗口容器(WindowContainer)的根容器,管理所有的窗口容器,设备上所有的窗口(Window)、显示屏幕(Display)都是由它来管理的。RootWindowContainer的resumeFocusedTasksTopActivities方法如下所示:

    frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

    class RootWindowContainer extends WindowContainer<DisplayContent>
            implements DisplayManager.DisplayListener {
        boolean resumeFocusedTasksTopActivities(
                Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
                boolean deferPause) {
            ...代码省略...
            boolean result = false;
            if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                    || getTopDisplayFocusedRootTask() == targetRootTask)) {
                result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                        deferPause);
            }
            for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
                final DisplayContent display = getChildAt(displayNdx);
                final boolean curResult = result;
                boolean[] resumedOnDisplay = new boolean[1];
                display.forAllRootTasks(rootTask -> {
                    final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
                    if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
                        return;
                    }
                    if (rootTask == targetRootTask) {
                        // Simply update the result for targetRootTask because the targetRootTask
                        // had already resumed in above. We don't want to resume it again,
                        // especially in some cases, it would cause a second launch failure
                        // if app process was dead.
                        resumedOnDisplay[0] |= curResult;
                        return;
                    }
                    if (rootTask.getDisplayArea().isTopRootTask(rootTask)
                            && topRunningActivity.isState(RESUMED)) {
                        // Kick off any lingering app transitions form the MoveTaskToFront
                        // operation, but only consider the top task and root-task on that
                        // display.
                        rootTask.executeAppTransition(targetOptions);
                    } else {
                        resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
                    }
                });
                result |= resumedOnDisplay[0];
                if (!resumedOnDisplay[0]) {
                    //获取当前屏幕设备的焦点任务栈
                    final Task focusedRoot = display.getFocusedRootTask();
                    if (focusedRoot != null) {
                        //如果焦点任务栈不为空则唤醒顶部的Activity
                        result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
                    } else if (targetRootTask == null) {
                        //否则唤醒首页Activity
                        result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                                display.getDefaultTaskDisplayArea());
                    }
                }
            }
            return result;
        }
    }
    

    resumeFocusedTasksTopActivities方法会恢复对应任务栈顶部的 Activity,如果没有合法的Activity则恢复首页Activity,如果有合法的Activity,则调用Task对象的resumeTopActivityUncheckedLocked方法来继续启动流程。

    6、Task用来描述一个Activity任务栈,Task的resumeTopActivityUncheckedLocked方法如下所示:

    frameworks/base/services/core/java/com/android/server/wm/Task.java

    class Task extends TaskFragment {
    
       boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */);
        }
    }
    

    resumeTopActivityUncheckedLocked内部直接调用了同名但参数不同的另一个方法:

        boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) {
            if (mInResumeTopActivity) {
                return false;
            }
            boolean someActivityResumed = false;
            try {
                mInResumeTopActivity = true;
                if (isLeafTask()) {
                    if (isFocusableAndVisible()) {
                        //继续调用resumeTopActivityInnerLocked方法
                        someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
                    }
                } else {
                    int idx = mChildren.size() - 1;
                    while (idx >= 0) {
                        final Task child = (Task) getChildAt(idx--);
                        if (!child.isTopActivityFocusable()) {
                            continue;
                        }
                        if (child.getVisibility(null /* starting */)
                                != TASK_FRAGMENT_VISIBILITY_VISIBLE) {
                            break;
                        }
                        someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options, deferPause);
                        if (idx >= mChildren.size()) {
                            idx = mChildren.size() - 1;
                        }
                    }
                }
                final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
                if (next == null || !next.canTurnScreenOn()) {
                    checkReadyForSleep();
                }
            } finally {
                mInResumeTopActivity = false;
            }
    
            return someActivityResumed;
        }
    

    该方法内部会进行一系列条件判断,最终会继续调用resumeTopActivityInnerLocked方法:

        private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
                boolean deferPause) {
            if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
                // Not ready yet!
                return false;
            }
            //获取当前顶部正在运行的Activity
            final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
            if (topActivity == null) {
                // There are no activities left in this task, let's look somewhere else.
                //如果根任务栈为空则返回下一个焦点Activity
                return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
            }
    
            final boolean[] resumed = new boolean[1];
            //获取当前顶部正在运行的Activity的TaskFragment
            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];
        }
    

    resumeTopActivityInnerLocked会调用父类TaskFragment的一个关键方法resumeTopActivity来继续唤醒顶部Activity。

    7、TaskFragment的resumeTopActivity方法如下所示:

        final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
                                        boolean deferPause) {
             ...代码省略...
            //进程存在
            if (next.attachedToProcess()) {
                ...代码省略...
                try {
                    next.completeResumeLocked();
                } catch (Exception e) {
                    ...代码省略...
                }
            } else {//进程不存在
                ...代码省略...
                mTaskSupervisor.startSpecificActivity(next, true, true);
            }
            return true;
        }
    

    由于前面已经将对应 Activity 的 ActivityRecord 添加到了栈顶,所以resumeTopActivity方法恢复的就是即将启动的栈顶 Activity,该方法中做了一系列判断,确保待启动 Activity 可见性、预定 Activity 的切换动画等。然后会判断将要启动的Activity进程是否存在,如果存在则会调用ActivityRecord的completeResumeLocked方法:

        void completeResumeLocked() {
            final boolean wasVisible = mVisibleRequested;
            setVisibility(true);
            if (!wasVisible) {
                // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
                mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
            }
            idle = false;
            results = null;
            if (newIntents != null && newIntents.size() > 0) {
                mLastNewIntent = newIntents.get(newIntents.size() - 1);
            }
            newIntents = null;
            stopped = false;
    
            if (isActivityTypeHome()) {
                mTaskSupervisor.updateHomeProcess(task.getBottomMostActivity().app);
            }
    
            if (nowVisible) {
                mTaskSupervisor.stopWaitingForActivityVisible(this);
            }
    
            // Schedule an idle timeout in case the app doesn't do it for us.
            mTaskSupervisor.scheduleIdleTimeout(this);
    
            mTaskSupervisor.reportResumedActivityLocked(this);
    
            resumeKeyDispatchingLocked();
            final Task rootTask = getRootTask();
            mTaskSupervisor.mNoAnimActivities.clear();
            returningOptions = null;
    
            if (canTurnScreenOn()) {
                mTaskSupervisor.wakeUp("turnScreenOnFlag");
            } else {
                // If the screen is going to turn on because the caller explicitly requested it and
                // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
                // pause and then resume again later, which will result in a double life-cycle event.
                rootTask.checkReadyForSleep();
            }
        }
    

    则会调用

    7、Task是一个管理类,用来管理系统所有Activity,其内部维护了Activity的所有状态、特殊状态的Activity以及和Activity相关的列表等数据,Task

    相关文章

      网友评论

          本文标题:Android 12系统源码_AMS(一)Activity启动流

          本文链接:https://www.haomeiwen.com/subject/vcqifdtx.html