首页 > 其他分享 >Activity相关学习(三)

Activity相关学习(三)

时间:2025-02-11 16:55:19浏览次数:50  
标签:启动 学习 intent && Activity 相关 null final

Activity启动流程(基于android-13.0.0_r83)

system_server进程启动Activity

在这里插入图片描述

执行ActivityTaskManagerService中的startActivity
    //frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    @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());
    }

主要步骤

  • 快速路径:
    如果启动选项包含 transientLaunch 标志,并且调用方是最近任务,则尝试快速启动最近任务。
  • 调用方验证:
    验证调用方的包名和 UID 是否匹配,并确保调用方不是隔离进程。
  • SDK 沙箱:
  • 如果调用方是 SDK 沙箱进程,则检查是否允许启动 Activity。
  • 目标用户验证:
    验证目标用户 ID 是否合法。
  • 启动 Activity:
    使用 ActivityStarter 启动 Activity,并返回启动结果。
     /*
     * @param caller 调用方的 IApplicationThread 对象,表示发起启动请求的应用线程。
     * @param callingPackage:调用方的包名。
     * @param callingFeatureId:调用方的 Feature ID(可以为 null)。
     * @param intent:要启动的 Activity 的 Intent。
     * @param resolvedType:Intent 的 MIME 类型。
     * @param resultTo:接收结果的 IBinder 对象(通常是当前 Activity 的令牌)。
     * @param resultWho:接收结果的标识符。
     * @param startFlags:启动标志位。
     * @param profilerInfo:性能分析信息(可以为 null)
     * @param bOptions:启动选项(如动画、过渡效果等)。
     * @param userId:目标用户 ID。
     * @param validateIncomingUser:是否验证传入的用户 ID。
     *
     * @return 返回一个整数值,表示启动结果(如 ActivityManager.START_SUCCESS)。
     */                  
    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) {
        //处理启动选项
        //将传入的 Bundle 启动选项转换为 SafeActivityOptions 对象。
        //SafeActivityOptions 是对 ActivityOptions 的封装,用于确保启动选项的安全性。
        final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
        // 快速路径:启动最近任务
        // 如果启动选项包含 transientLaunch 标志,并且调用方是最近任务(Recents),则尝试快速启动最近任务。
        if (opts != null && opts.getOriginalOptions().getTransientLaunch()
                && isCallerRecents(Binder.getCallingUid())) {
            final long origId = Binder.clearCallingIdentity();
            try {
                synchronized (mGlobalLock) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
                    //尝试启动现有的最近任务。
                    if (mActivityStartController.startExistingRecentsIfPossible(
                            intent, opts.getOriginalOptions())) {
                        //如果成功,则返回 ActivityManager.START_TASK_TO_FRONT,表示任务已前置。
                        return ActivityManager.START_TASK_TO_FRONT;
                    }
                    // Else follow the standard launch procedure.
                }
            } finally {
                //清除和恢复调用方的身份信息,确保在系统权限下执行操作。
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                Binder.restoreCallingIdentity(origId);
            }
        }
        //验证调用方的包名是否与调用方的 UID 匹配。
        assertPackageMatchesCallingUid(callingPackage);
        //确保调用方不是隔离进程(isolated process)。
        enforceNotIsolatedCaller("startActivityAsUser");
        //如果调用方是 SDK 沙箱进程,则检查是否允许启动 Activity。
        if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
            SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
                    SdkSandboxManagerLocal.class);
            if (sdkSandboxManagerLocal == null) {
                throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
                        + " an activity from an SDK sandbox uid.");
            }
            //验证 Intent 的合法性。
            sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
        }
        //验证目标用户 ID 是否合法。
        //如果 validateIncomingUser 为 true,则进一步验证传入的用户 ID。
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // 获取一个 ActivityStarter 实例,用于启动 Activity。
        //设置参数,设置调用方、包名、Feature ID、MIME 类型、结果接收者、请求代码、启动标志位、性能分析信息、启动选项和目标用户 ID。
        //execute:执行启动操作,并返回启动结果。
        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();

    }

执行ActivityStarter 中的execute
ActivityStarter

它是 ActivityTaskManagerService(ATMS)的一部分,负责处理 Activity 启动的复杂逻辑,包括解析 Intent、处理启动模式、管理任务栈等。ActivityStarter 的设计目标是将 Activity 启动的逻辑集中化,便于维护和扩展。
主要作用

  • 解析 Intent: 解析启动 Activity 的 Intent,确定目标 Activity。
  • 处理启动模式: 根据 Activity 的启动模式(如 standard、singleTop、singleTask 等)决定是否创建新的 Activity 实例或复用现有实例。
  • 管理任务栈: 确定目标 Activity 应该运行在哪个任务栈(Task)中。
  • 处理权限和安全性: 检查调用方是否有权限启动目标 Activity。
  • 处理多窗口模式: 在多窗口模式下,确定 Activity 的显示位置和大小。
  • 调用生命周期方法: 触发目标 Activity 的生命周期方法(如 onCreate()、onStart()、onResume())。
execute()
  • mRequest:表示Activity启动请求的对象,包含了启动Activity所需的所有信息,如Intent、调用者信息、权限等。
  • mService:表示系统的全局服务,可能是 ActivityManagerService 或类似的系统服务。
  • mSupervisor:ActivityStackSupervisor,负责管理Activity栈和任务。
  • mRootWindowContainer:表示窗口容器的根节点,管理所有显示器的窗口和任务栈。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/*
* 方法负责执行一个Activity启动请求,处理从请求开始到结束的整个流程
*/
int execute() {
        try {
            //可能是用于通知系统或记录日志,表示Activity启动流程已经开始
            onExecutionStarted();

            //文件描述符检查:检查Intent中是否包含文件描述符。如果包含,抛出 IllegalArgumentException 异常,防止文件描述符泄漏
            if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
                throw new IllegalArgumentException("File descriptors passed in Intent");
            }

            final LaunchingState launchingState;
            synchronized (mService.mGlobalLock) {
                //获取调用者的 ActivityRecord,用于标识启动Activity的调用者
                final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
                //获取调用者的UID,用于权限检查
                final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
                        ?  Binder.getCallingUid() : mRequest.realCallingUid;
                //记录Activity的启动状态。这个步骤可能用于性能监控或日志记录
                launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
                        mRequest.intent, caller, callingUid);
            }

            //表示调用者尚未解析目标Activity,此时调用 mRequest.resolveActivity(mSupervisor) 进行解析。
            if (mRequest.activityInfo == null) {
                //确保在启动Activity之前,目标Activity的信息已经被正确解析
                mRequest.resolveActivity(mSupervisor);
            }

            // 如果Intent的Action是 ACTION_REQUEST_SHUTDOWN、ACTION_SHUTDOWN 或 ACTION_REBOOT,表示系统正在执行关机或重启操作。
            if (mRequest.intent != null) {
                String intentAction = mRequest.intent.getAction();
                String callingPackage = mRequest.callingPackage;
                if (intentAction != null && callingPackage != null
                        && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
                                || Intent.ACTION_SHUTDOWN.equals(intentAction)
                                || Intent.ACTION_REBOOT.equals(intentAction))) {
                    //可能是为了在系统重启后能够恢复现场
                    ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
                }
            }
            int res;
            synchronized (mService.mGlobalLock) {
               //检查全局配置是否发生变化(globalConfigWillChange)。如果发生变化,更新配置并通知相关组件。
                final boolean globalConfigWillChange = mRequest.globalConfig != null
                        && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
                final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
                if (rootTask != null) {
                    rootTask.mConfigWillChange = globalConfigWillChange;
                }
                ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
                        + "will change = %b", globalConfigWillChange);

                final long origId = Binder.clearCallingIdentity();
                //检查是否需要切换到重量级Activity(例如,从普通Activity切换到分屏模式)。如果需要切换,返回相应的结果。
                res = resolveToHeavyWeightSwitcherIfNeeded();
                if (res != START_SUCCESS) {
                    return res;
                }
                //执行实际的Activity启动请求
                res = executeRequest(mRequest);
                //用于清除和恢复调用者的身份信息,确保在执行关键操作时权限正确。
                Binder.restoreCallingIdentity(origId);

                if (globalConfigWillChange) {
                    mService.mAmInternal.enforceCallingPermission(
                            android.Manifest.permission.CHANGE_CONFIGURATION,
                            "updateConfiguration()");
                    if (rootTask != null) {
                        //标记任务栈的配置是否发生变化
                        rootTask.mConfigWillChange = false;
                    }
                    ProtoLog.v(WM_DEBUG_CONFIGURATION,
                                "Updating to new configuration after starting activity.");
                    //更新系统的全局配置
                    mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
                }
                final ActivityOptions originalOptions = mRequest.activityOptions != null
                        ? mRequest.activityOptions.getOriginalOptions() : null;
                final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
                // 通知 ActivityMetricsLogger,Activity已经启动。这一步可能用于记录Activity启动的性能数据。
                mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
                        newActivityCreated, mLastStartActivityRecord, originalOptions);
                if (mRequest.waitResult != null) {
                    mRequest.waitResult.result = res;
                    //如果需要等待启动结果,调用此方法进行等待
                    res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
                            launchingState);
                }
                //将内部的结果转换为外部可用的结果并返回
                return getExternalResult(res);
            }
        } finally {
            //用于释放资源或执行一些清理操作
            onExecutionComplete();
        }
    }
executeRequest

executeRequest比较长分部分分析,主要分为5个部分

  • 准备参数
  • 各类权限检测
  • 启动过程拦截器处理
  • 构建待启动的目标 Activity 对应的 ActivityRecord 对象
  • 调用 startActivityUnchecked 方法
  1. 参数准备
  • 检查 request.reason:确保启动请求有一个明确的原因,否则抛出异常。
  • 记录启动信息:保存启动原因、启动时间等,用于日志记录或调试。
  • 提取请求参数:从 Request 对象中提取启动 Activity 所需的各种参数,如 Intent、ActivityInfo、callingUid、callingPackage 等。
    private int executeRequest(Request request) {
        //检查确保每个Activity启动请求都有一个明确的原因,可能是为了日志记录、调试或权限控制
        if (TextUtils.isEmpty(request.reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = request.reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();//记录当前时间
        mLastStartActivityRecord = null;

        //提取请求参数
        final IApplicationThread caller = request.caller;
        Intent intent = request.intent;
        NeededUriGrants intentGrants = request.intentGrants;//表示Intent所需的URI权限
        String resolvedType = request.resolvedType;
        ActivityInfo aInfo = request.activityInfo;//表示目标Activity的信息(如包名、类名、权限等)
        ResolveInfo rInfo = request.resolveInfo;//表示解析Intent后得到的目标组件信息
        final IVoiceInteractionSession voiceSession = request.voiceSession;
        final IBinder resultTo = request.resultTo;
        String resultWho = request.resultWho;
        int requestCode = request.requestCode;
        int callingPid = request.callingPid;
        int callingUid = request.callingUid;
        String callingPackage = request.callingPackage;
        String callingFeatureId = request.callingFeatureId;
        final int realCallingPid = request.realCallingPid;
        final int realCallingUid = request.realCallingUid;
        final int startFlags = request.startFlags;
        final SafeActivityOptions options = request.activityOptions;
        Task inTask = request.inTask;//表示目标Activity所属的任务栈
        TaskFragment inTaskFragment = request.inTaskFragment;
        ...
  }
  1. 权限检查

检查WindowProcessController能不能获取,如果不能,报权限异常。

    private int executeRequest(Request request) {
        int err = ActivityManager.START_SUCCESS;
        // 这是一个可选的数据包,用于应用安装验证
        final Bundle verificationBundle =
                options != null ? options.popAppVerificationBundle() : null;
        //存储调用者进程的信息
        WindowProcessController callerApp = null;
        //caller 是一个 IApplicationThread 对象,表示调用者进程的 Binder 接口
        if (caller != null) {
            //获取调用者进程的 WindowProcessController 对象,
            //WindowProcessController 是 Android 系统中用于管理进程状态的对象,包含进程的 PID、UID 等信息
            callerApp = mService.getProcessController(caller);
            if (callerApp != null) {
                //提取调用者的 PID 和 UID
                callingPid = callerApp.getPid();
                callingUid = callerApp.mInfo.uid;
            } else {
                //记录警告日志并设置错误码
                Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
                        + ") when starting: " + intent.toString());
                err = START_PERMISSION_DENIED;
            }
        }

        //初始化 userId
        final int userId = aInfo != null && aInfo.applicationInfo != null
                ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
        if (err == ActivityManager.START_SUCCESS) {
            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
                    + "} from uid " + callingUid);
        }
        ...
    }

startActivityForResult相关业务处理,主要确定是不是这个业务,如果是,找到正确的sourceRecord和resultRecord。

    private int executeRequest(Request request) {
        //存储发起请求的Activity记录
        ActivityRecord sourceRecord = null;
        //存储结果返回的目标Activity记录
        ActivityRecord resultRecord = null;
        //是一个 IBinder 对象,表示请求结果的接收者
        if (resultTo != null) {
            sourceRecord = ActivityRecord.isInAnyTask(resultTo);
            if (DEBUG_RESULTS) {
                Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
            }
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
        final int launchFlags = intent.getFlags();
        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
            // Transfer the result target from the source activity to the new one being started,
            // including any failures.
            if (requestCode >= 0) {
                SafeActivityOptions.abort(options);
                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
            }
            resultRecord = sourceRecord.resultTo;
            if (resultRecord != null && !resultRecord.isInRootTaskLocked()) {
                resultRecord = null;
            }
            resultWho = sourceRecord.resultWho;
            requestCode = sourceRecord.requestCode;
            sourceRecord.resultTo = null;
            if (resultRecord != null) {
                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
            }
            if (sourceRecord.launchedFromUid == callingUid) {
                callingPackage = sourceRecord.launchedFromPackage;
                callingFeatureId = sourceRecord.launchedFromFeatureId;
            }
        }
        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
            // We couldn't find a class that can handle the given Intent.
            // That's the end of that!
            err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }

        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
            // We couldn't find the specific class specified in the Intent.
            // Also the end of the line.
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }

        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
                && sourceRecord.getTask().voiceSession != null) {
            if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
                try {
                    intent.addCategory(Intent.CATEGORY_VOICE);
                    if (!mService.getPackageManager().activitySupportsIntent(
                            intent.getComponent(), intent, resolvedType)) {
                        Slog.w(TAG, "Activity being started in current voice task does not support "
                                + "voice: " + intent);
                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
                    }
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failure checking voice capabilities", e);
                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
                }
            }
        }
        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
            // If the caller is starting a new voice session, just make sure the target
            // is actually allowing it to run this way.
            try {
                if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
                        intent, resolvedType)) {
                    Slog.w(TAG,
                            "Activity being started in new voice task does not support: " + intent);
                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Failure checking voice capabilities", e);
                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
            }
        }

        final Task resultRootTask = resultRecord == null
                ? null : resultRecord.getRootTask();

        if (err != START_SUCCESS) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                        null /* data */, null /* dataGrants */);
            }
            SafeActivityOptions.abort(options);
            return err;
        }
        

通过ATS、ActivityManager、PermissionPolicyService检查是否有启动Activity的权限,如果没有终止启动。

private int executeRequest(Request request) {
        //权限检查返回的 abort 为 false,表示有权限启动目标 Activity
        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
                request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
                resultRootTask);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
        abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
                callingPackage);
                        // Merge the two options bundles, while realCallerOptions takes precedence.
        ActivityOptions checkedOptions = options != null
                ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;

        //后台启动控制
        @BalCode int balCode = BAL_ALLOW_DEFAULT;
        if (!abort) {
            try {
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
                        "shouldAbortBackgroundActivityStart");
                BackgroundActivityStartController balController =
                        mController.getBackgroundActivityLaunchController();
                balCode =
                        balController.checkBackgroundActivityStart(
                                callingUid,
                                callingPid,
                                callingPackage,
                                realCallingUid,
                                realCallingPid,
                                callerApp,
                                request.originatingPendingIntent,
                                request.allowBackgroundActivityStart,
                                intent,
                                checkedOptions);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            }
        }
        if (request.allowPendingRemoteAnimationRegistryLookup) {
            checkedOptions = mService.getActivityStartController()
                    .getPendingRemoteAnimationRegistry()
                    .overrideOptionsIfNeeded(callingPackage, checkedOptions);
        }
        if (mService.mController != null) {
            try {
                // The Intent we give to the watcher has the extra data stripped off, since it
                // can contain private information.
                Intent watchIntent = intent.cloneFilter();
                abort |= !mService.mController.activityStarting(watchIntent,
                        aInfo.applicationInfo.packageName);
            } catch (RemoteException e) {
                mService.mController = null;
            }
        }

启动过程拦截器处理,调用ActivityStartInterceptor的intercept方法对满足条件进行activity启动拦截。

    private int executeRequest(Request request) {
        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
                callingFeatureId);
        if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
                callingPid, callingUid, checkedOptions)) {
            // activity start was intercepted, e.g. because the target user is currently in quiet
            // mode (turn off work) or the target application is suspended
            intent = mInterceptor.mIntent;
            rInfo = mInterceptor.mRInfo;
            aInfo = mInterceptor.mAInfo;
            resolvedType = mInterceptor.mResolvedType;
            inTask = mInterceptor.mInTask;
            callingPid = mInterceptor.mCallingPid;
            callingUid = mInterceptor.mCallingUid;
            checkedOptions = mInterceptor.mActivityOptions;

            // The interception target shouldn't get any permission grants
            // intended for the original destination
            intentGrants = null;
        }
        if (abort) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                        null /* data */, null /* dataGrants */);
            }
            // We pretend to the caller that it was really started, but they will just get a
            // cancel result.
            ActivityOptions.abort(checkedOptions);
            return START_ABORTED;
        }
        if (aInfo != null) {
            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                    aInfo.packageName, userId)) {
                final IIntentSender target = mService.getIntentSenderLocked(
                        ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
                        callingUid, userId, null, null, 0, new Intent[]{intent},
                        new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
                                | PendingIntent.FLAG_ONE_SHOT, null);

                Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);

                int flags = intent.getFlags();
                flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;

                if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
                    flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
                }
                newIntent.setFlags(flags);

                newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
                newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
                if (resultRecord != null) {
                    newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
                }
                intent = newIntent;
                                intentGrants = null;

                resolvedType = null;
                callingUid = realCallingUid;
                callingPid = realCallingPid;

                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
                        computeResolveFilterUid(
                                callingUid, realCallingUid, request.filterCallingUid));
                aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
                        null /*profilerInfo*/);

                if (DEBUG_PERMISSIONS_REVIEW) {
                    final Task focusedRootTask =
                            mRootWindowContainer.getTopDisplayFocusedRootTask();
                    Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
                            true, false) + "} from uid " + callingUid + " on display "
                            + (focusedRootTask == null ? DEFAULT_DISPLAY
                                    : focusedRootTask.getDisplayId()));
                }
            }
        }
                if (rInfo != null && rInfo.auxiliaryInfo != null) {
            intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
                    callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
            resolvedType = null;
            callingUid = realCallingUid;
            callingPid = realCallingPid;

            // The ephemeral installer shouldn't get any permission grants
            // intended for the original destination
            intentGrants = null;

            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
        }
        // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
        // Pending intent launched from systemui also depends on caller app
        if (callerApp == null && realCallingPid > 0) {
            final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
            if (wpc != null) {
                callerApp = wpc;
            }
        }

创建启动目标Activity的ActivityRecord。
调用 startActivityUnchecked 方法

    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();

        mLastStartActivityRecord = r;

        if (r.appTimeTracker == null && sourceRecord != null) {
            // If the caller didn't specify an explicit time tracker, we want to continue
            // tracking under any it has.
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }
                WindowProcessController homeProcess = mService.mHomeProcess;
        boolean isHomeProcess = homeProcess != null
                && aInfo.applicationInfo.uid == homeProcess.mUid;
        if (balCode != BAL_BLOCK && !isHomeProcess) {
            mService.resumeAppSwitches();
        }

        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
                inTask, inTaskFragment, balCode, intentGrants);

        if (request.outActivity != null) {
            request.outActivity[0] = mLastStartActivityRecord;
        }

        return mLastStartActivityResult;
    }
startActivityUnchecked

负责在完成初步校验后执行具体的启动流程。

     /*
     * @param r 目标Activity的记录。
     * @param sourceRecord:发起启动请求的Activity记录。
     * @param voiceSession:语音交互相关参数。
     * @param voiceInteractor:。
     * @param startFlags:启动标志(如FLAG_ACTIVITY_NEW_TASK)。
     * @param doResume:是否立即恢复目标Activity。
     * @param options:启动选项(如动画、窗口模式)。
     * @param inTask:目标Activity所属的Task和TaskFragment。
     * @param inTaskFragment:
     * @param balCode:后台启动检查的结果代码。
     * @param intentGrants:URI权限授予信息。
     *
     * @return 启动结果(如START_SUCCESS、START_CANCELED)。
     */ 
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, @BalCode int balCode,
            NeededUriGrants intentGrants) {
        int result = START_CANCELED;//默认启动失败
        final Task startedActivityRootTask;

        // Transition管理
        // 创建Transition对象以记录启动过程中的动画和状态变化
        // 仅在未收集Transition且存在TransitionPlayer时创建新Transition
        final TransitionController transitionController = r.mTransitionController;
        Transition newTransition = (!transitionController.isCollecting()
                && transitionController.getTransitionPlayer() != null)
                ? transitionController.createTransition(TRANSIT_OPEN) : null;
        RemoteTransition remoteTransition = r.takeRemoteTransition();
        try {
            //延迟窗口布局更新,避免启动过程中的布局抖动
            mService.deferWindowLayout();
            //收集目标Activity的状态
            transitionController.collect(r);
            try {
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
                //启动核心逻辑
                result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, doResume, options, inTask, inTaskFragment, balCode,
                        intentGrants);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
                //处理启动结果,返回目标Activity的根Task
                startedActivityRootTask = handleStartResult(r, options, result, newTransition,
                        remoteTransition);
            }
        } finally {
            //确保无论启动成功与否,窗口布局最终恢复
            mService.continueWindowLayout();
        }
        //在启动完成后执行后续处理逻辑(如日志记录、回调通知)
        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }
startActivityInner

启动一个activity,包括任务(Task)的管理、Activity 的复用、权限检查、任务栈的调整等。

    @VisibleForTesting
    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, @BalCode int balCode,
            NeededUriGrants intentGrants) {
        //初始化了启动 Activity 所需的状态
        setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
                voiceSession, voiceInteractor, balCode);
        //计算启动 Activity 时所需的标志位(flags),这些标志位决定了 Activity 如何启动(例如是否在新的任务栈中启动)
        computeLaunchingTaskFlags();
        mIntent.setFlags(mLaunchFlags);

        boolean dreamStopping = false;
        //检查是否有正在停止的 Dream Activity(例如屏保或屏保类应用)
        for (ActivityRecord stoppingActivity : mSupervisor.mStoppingActivities) {
            if (stoppingActivity.getActivityType()
                    == WindowConfiguration.ACTIVITY_TYPE_DREAM) {
                dreamStopping = true;
                break;
            }
        }

        // 获取当前显示区域(DisplayArea)中聚焦的根任务栈(RootTask)以及顶部的任务栈(Task).
        final Task prevTopRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
        final Task prevTopTask = prevTopRootTask != null ? prevTopRootTask.getTopLeafTask() : null;
        final Task reusedTask = getReusableTask();//尝试获取一个可以复用的任务栈,避免创建新的任务栈

        // 如果启动 Activity 时需要冻结最近任务列表(例如从最近任务列表中启动应用),则设置冻结标志,防止任务列表重新排序
        if (mOptions != null && mOptions.freezeRecentTasksReordering()
                && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
                && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
            mFrozeTaskList = true;
            mSupervisor.mRecentTasks.setFreezeTaskListReordering();
        }
       //计算目标任务栈
       //如果存在可复用的任务栈,则使用该任务栈;否则,调用 computeTargetTask() 计算一个新的目标任务栈
        final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
        final boolean newTask = targetTask == null;//表示是否需要在新的任务栈中启动 Activity
        mTargetTask = targetTask;

        computeLaunchParams(r, sourceRecord, targetTask);

        // 检查当前是否有权限启动目标 Activity。如果没有权限,则返回错误码,并通知调用方启动失败
        int startResult = isAllowedToStart(r, newTask, targetTask);
        if (startResult != START_SUCCESS) {
            if (r.resultTo != null) {
                r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED,
                        null /* data */, null /* dataGrants */);
            }
            return startResult;
        }

        //如果目标任务栈不为空,并且栈顶有未结束的 Activity,则尝试复用该任务栈
        //如果复用失败,则设置 mAddingToTask 标志,表示需要将 Activity 添加到现有任务栈中。
        if (targetTask != null) {
            mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask());
        }

        final ActivityRecord targetTaskTop = newTask
                ? null : targetTask.getTopNonFinishingActivity();
        if (targetTaskTop != null) {
            // Recycle the target task for this launch.
            startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
            if (startResult != START_SUCCESS) {
                return startResult;
            }
        } else {
            mAddingToTask = true;
        }
        
        // 如果当前有聚焦的根任务栈,则检查是否需要将启动的 Activity 交付给当前顶部的 Activity 处理
        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);
        }
        if (newTask) {
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            //如果需要在新任务栈中启动 Activity,则调用 setNewTask() 设置新任务栈
            setNewTask(taskToAffiliate);
        } else if (mAddingToTask) {
            //将 Activity 添加到现有任务栈中
            addOrReparentStartingActivity(targetTask, "adding to task");
        }

        //如果不需要避免将任务栈移到前台,并且需要恢复 Activity,则将目标根任务栈移到前台
        //如果当前系统处于 Dream 模式(例如屏保),并且目标根任务栈不在顶部,则设置 mLaunchTaskBehind 标志,表示 Activity 需要在后台启动
        if (!mAvoidMoveToFront && mDoResume) {
            mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
            if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
                    && !dreamStopping) {
                mLaunchTaskBehind = true;
                r.mLaunchTaskBehind = true;
            }
        }
        //授予目标 Activity 所需的 URI 权限
        mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
                mStartActivity.getUriPermissionsLocked());
        //如果启动的 Activity 需要返回结果给调用方,则授予调用方隐式访问权限
        if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
            final PackageManagerInternal pmInternal =
                    mService.getPackageManagerInternalLocked();
            final int resultToUid = pmInternal.getPackageUid(
                    mStartActivity.resultTo.info.packageName, 0 /* flags */,
                    mStartActivity.mUserId);
            pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
                    UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
                    resultToUid /*visible*/, true /*direct*/);
        }
        //记录任务和 Activity 的创建
        final Task startedTask = mStartActivity.getTask();
        if (newTask) {
            EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
        }
        mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);

        mStartActivity.getTaskFragment().clearLastPausedActivity();

        mRootWindowContainer.startPowerModeLaunchIfNeeded(
                false /* forceSend */, mStartActivity);

        final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded();
        mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
                mOptions, sourceRecord);
        //如果需要恢复 Activity,则确保目标根任务栈中的 Activity 可见。
        //如果目标根任务栈的顶部 Activity 不可聚焦(例如画中画模式),则确保所有 Activity 可见,并执行应用过渡动画。
        //否则,将目标根任务栈移到前台,并恢复其顶部 Activity。
        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");
                }
                mRootWindowContainer.resumeFocusedTasksTopActivities(
                        mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
            }
        }
        //更新用户的任务栈信息
        mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);

        // 将启动的任务栈添加到最近任务列表中
        mSupervisor.mRecentTasks.add(startedTask);
        //处理不可调整大小的任务栈(例如固定方向的任务栈)
        mSupervisor.handleNonResizableTaskIfNeeded(startedTask,
                mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);

        // 如果启动的 Activity 需要进入画中画模式(PIP),则将其移动到画中画任务栈中.
        if (mOptions != null && mOptions.isLaunchIntoPip()
                && sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
                && balCode != BAL_BLOCK) {
            mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
                    sourceRecord, "launch-into-pip");
        }

        return START_SUCCESS;
    }
       
resumeFocusedTasksTopActivities
resumeTopActivityUncheckedLocked
resumeTopActivityInnerLocked
schedulePauseActivity

在启动Activity之前,将App进程中的Activity暂停

    //frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
            boolean pauseImmediately, boolean autoEnteringPip, String reason) {
        ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
        try {
            EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                    prev.shortComponentName, "userLeaving=" + userLeaving, reason);

            mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately, autoEnteringPip));
        } catch (Exception e) {
            // Ignore exception, if process died other code will cleanup.
            Slog.w(TAG, "Exception thrown during pause", e);
            mPausingActivity = null;
            mLastPausedActivity = null;
            mTaskSupervisor.mNoHistoryActivities.remove(prev);
        }
    }
resumeTopActivity
    //frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
    final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
            ...
            //
            mTaskSupervisor.startSpecificActivity(next, true, true);
             ...
    }
startSpecificActivity

检查目标 Activity 所在的应用程序进程是否已经运行,并根据进程状态决定是直接启动 Activity 还是先启动应用程序进程

   //frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                //如果目标进程已经运行且存活(wpc.hasThread() 为 true),则调用 realStartActivityLocked 方法直接启动 Activity。
                //realStartActivityLocked 是真正启动 Activity 的核心方法,负责将 Activity 添加到任务栈中并触发其生命周期回调。
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
            // Remove the process record so it won't be considered as alive.
            mService.mProcessNames.remove(wpc.mName, wpc.mUid);
            mService.mProcessMap.remove(wpc.getPid());
        }
        //如果进程已经死亡,则调用 notifyUnknownVisibilityLaunchedForKeyguardTransition 方法通知系统,目标 Activity 的可见性状态可能发生变化(例如从锁屏界面启动 Activity)
        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        //如果目标进程不存在或已经死亡,则调用 mService.startProcessAsync 方法异步启动应用程序进程。
        final boolean isTop = andResume && r.isTopRunningActivity();
        //isTop 表示目标 Activity 是否是当前顶部的 Activity
        //knownToBeDead 表示目标进程是否已经死亡
        mService.startProcessAsync(r, knownToBeDead, isTop,
                isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
                        : HostingRecord.HOSTING_TYPE_ACTIVITY);
    }

标签:启动,学习,intent,&&,Activity,相关,null,final
From: https://blog.csdn.net/linwq8/article/details/145536752

相关文章