本文基于 android-10.0.0_r41 版本讲解
到了服务端这边,从前面的分析我们知道,当前情景下的工作大概就是:
- 构造一个目标 Activity 对应的 ActivityRecord 对象
- 构造目标 App 的 ActivityStack 对象
- 构造目标任务栈 TaskRecord
- 把 ActivityRecord 插入到 TaskRecord
我们按照这个流程按图索骥:
上一节我们分析到客户端发起 Binder RPC 调用,接下来就会远程调用到 SystemServer 进程中 ActivityTaskManagerService 服务的 startActivity 方法:
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.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());
}
方法的参数有:
- IApplicationThread caller:启动方应用的 ActivityThread 对象的 ApplicationThread 类型成员 mAppThread
- String callingPackage:启动方 Activity 所在包名 "com.android.launcher3"
- Intent intent:启动目的 Activity 的 Intent,携带了目的端 Acitivity 隐式或者显示启动需要的参数
- String resolvedType:the MIME data type of this intent
- IBinder resultTo:指向发起端 Activity 的 ActivityRecord 对象中的 Token
- String resultWho:来自于当前发起端 Activity.mEmbeddedID
- int requestCode:启动目的端 Activity 的请求码
- int startFlags:Activity 的启动 flag
- ProfilerInfo profilerInfo:System private API for passing profiler settings,这里是 null
- Bundle bOptions:启动 Activity 的额外参数
接着调用 startActivityAsUser:
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public 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*/);
}
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) {
// 确定调用方 uid 的合法性
enforceNotIsolatedCaller("startActivityAsUser");
// 当前情景下,userId =0
// pid 与 userid 相关的权限判断和调整,了解一下即可。
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// 关注点1
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
关注点 1 处,先调用 getActivityStartController
方法,方法中返回 ActivityTaskManagerService 类的成员变量 mActivityStartController。
java
// base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
mActivityStartController 是 ActivityTaskManagerService 类的成员,ATMS 中 Activity 启动相关的功能都放在 ActivityStartController 类中:
java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// ......
private ActivityStartController mActivityStartController;
// ......
}
mActivityStartController 在 ActivityTaskManagerService 的 initialize 方法中初始化
java
// base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController,
Looper looper) {
// ......
mActivityStartController = new ActivityStartController(this);
// ......
}
// ActivityStartController 构造函数
ActivityStartController(ActivityTaskManagerService service) {
this(service, service.mStackSupervisor,
new DefaultFactory(service, service.mStackSupervisor,
new ActivityStartInterceptor(service, service.mStackSupervisor)));
}
ActivityStartController(ActivityTaskManagerService service, ActivityStackSupervisor supervisor,
Factory factory) {
mService = service;
mSupervisor = supervisor;
mHandler = new StartHandler(mService.mH.getLooper());
mFactory = factory;
mFactory.setController(this);
mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service,
service.mH);
}
这里需要注意 ActivityStartController 的成员 mFactory 初始化为 DefaultFactory 对象。
回到启动过程代码,接着会调用 mActivityStartController 的 obtainStarter 方法:
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
这里的 mFactory 就是 ActivityStartController 初始化过程中的 DefaultFactory,会调用其 obtaion 方法初始化一个 ActivityStarter 对象返回。
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
static class DefaultFactory implements Factory {
// ......
@Override
public ActivityStarter obtain() {
ActivityStarter starter = mStarterPool.acquire();
if (starter == null) {
starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
}
return starter;
}
// ......
}
接着给 ActivityStarter 对象设置一堆参数:
java
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
最后调用 ActivityStarter 的 execute 方法。
java
// base/services/core/java/com/android/server/wm/ActivityStarter.java
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.realCallingPid, mRequest.realCallingUid,
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,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} 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,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
// base/services/core/java/com/android/server/wm/ActivityStarter.java
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
设置参数过程中会调用 setMayWait 方法会将 mRequest.mayWait 设置为 true,所以上面的代码会走第一个 if 分支执行到 startActivityMayWait
方法。startActivityMayWait
方法很长,我们分步查看:
java
// base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
// 启动 Activity 不能通过 intent 传递 fd
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
// ActivityMetricsLogger 用于记录 Activity 启动、绘制等时间,用于程序分析
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
//intent 中是否有 Component,这里是 true
boolean componentSpecified = intent.getComponent() != null;
// 获取几个 id
final int realCallingPid = requestRealCallingPid != Request.DEFAULT_REAL_CALLING_PID
? requestRealCallingPid
: Binder.getCallingPid();
final int realCallingUid = requestRealCallingUid != Request.DEFAULT_REAL_CALLING_UID
? requestRealCallingUid
: Binder.getCallingUid();
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
} else if (caller == null) {
callingPid = realCallingPid;
callingUid = realCallingUid;
} else {
callingPid = callingUid = -1;
}
// instant App 使用的,当前情景不用关心
// Save a copy in case ephemeral needs it
final Intent ephemeralIntent = new Intent(intent);
// Don't modify the client's object!
// 以传递进来的 intent 为参数重新创建新的 Intent 对象,即便 intent 被修改也不受影响
intent = new Intent(intent);
// ......
// 通过 PackageManagerService 获取到目标 Activity 信息, 当存在多个可供选择的 Activity,则直接向用户弹出 resolveActivity
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
0 /* matchFlags */,
computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
if (rInfo == null) {
// ......
}
// .......
resolveIntent 方法通过调用 PackageManagerService 服务(这里是 LocalService,没有进程间通信),查询目的端 Activity 的相关信息,查询到的信息保存在 ResolveInfo 对象中:
java
// base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
int filterCallingUid) {
try {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "resolveIntent");
int modifiedFlags = flags
| PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS;
if (intent.isWebIntent()
|| (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
modifiedFlags |= PackageManager.MATCH_INSTANT;
}
// In order to allow cross-profile lookup, we clear the calling identity here.
// Note the binder identity won't affect the result, but filterCallingUid will.
// Cross-user/profile call check are done at the entry points
// (e.g. AMS.startActivityAsUser).
final long token = Binder.clearCallingIdentity();
try {
// 调用 PackageManagerService LocalService
return mService.getPackageManagerInternalLocked().resolveIntent(
intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
} finally {
Binder.restoreCallingIdentity(token);
}
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
这里会调用到 PackageManagerService 中的 resolveIntent 来查询目标 Activity 的信息,需要注意的是 ATMS 和 PackageManagerService 都在 SystemServer 中运行,这里使用的是 LocalService,不是 Binder RPC 调用。
从 PackageManagerService 中查询到的信息会保存在返回的 ResolveInfo 对象中:
java
public class ResolveInfo implements Parcelable {
private static final String TAG = "ResolveInfo";
public ActivityInfo activityInfo;
public ServiceInfo serviceInfo;
public ProviderInfo providerInfo;
public AuxiliaryResolveInfo auxiliaryInfo;
public boolean isInstantAppAvailable;
@Deprecated
public boolean instantAppAvailable;
public IntentFilter filter;
public int priority;
public int preferredOrder;
public int match;
public int specificIndex = -1;
public boolean isDefault;
public int labelRes;
public CharSequence nonLocalizedLabel;
public int icon;
public String resolvePackageName;
@UnsupportedAppUsage
public int targetUserId;
public boolean noResourceId;
public int iconResourceId;
@UnsupportedAppUsage
public boolean system;
@SystemApi
public boolean handleAllWebDataURI;
// ......
}
ResolveInfo 中比较重要的成员有三个:
- ActivityInfo:用于存储 Activity 或 Broadcast 的信息
- ServiceInfo:用于存储 Service 相关信息
- ProviderInfo:用于存储 Content Provider 相关信息
这三个成员只有一个不为空,这里我们启动的是 Activity,所以 ActivityInfo 是不为空的。ActivityInfo 包含了各种各样的 Activity 信息,这些信息都是 PackageManagerService 从 AndroidManifest.xml
文件中获取到的,比较重要的包括 launchMode、theme、screenOrientation 等,其中还包含了 ApplicationInfo,提供 packageName、targetSdkVersion 等重要信息。
我们接着回到 startActivityMayWait 方法中:
java
// base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityMayWait(......) {
// ......
// 根据获取的 rInfo 信息重新配置 intent 和设置启动的参数信息
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
//......
}
resolveActivity 方法根据获取到的 ResolveInfo 信息重新配置 intent:
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
ProfilerInfo profilerInfo) {
final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
// Store the found target back into the intent, because now that
// we have it we never want to do this again. For example, if the
// user navigates back to this point in the history, we should
// always restart the exact same activity.
// 使用 rInfo 中的信息重新配置 intent 的 Component
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// 非 system 进程 && startFlags 中有特殊值
// 给 AMS 发送一个消息,使用 startFlags 设置 debug 相关的参数
// 了解即可
// Don't debug things in the system process
if (!aInfo.processName.equals("system")) {
if ((startFlags & (START_FLAG_DEBUG | START_FLAG_NATIVE_DEBUGGING
| START_FLAG_TRACK_ALLOCATION)) != 0 || profilerInfo != null) {
// Mimic an AMS synchronous call by passing a message to AMS and wait for AMS
// to notify us that the task has completed.
// TODO(b/80414790) look into further untangling for the situation where the
// caller is on the same thread as the handler we are posting to.
synchronized (mService.mGlobalLock) {
// Post message to AMS.
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::setDebugFlagsForStartingActivity,
mService.mAmInternal, aInfo, startFlags, profilerInfo,
mService.mGlobalLock);
mService.mH.sendMessage(msg);
try {
// 等待锁
mService.mGlobalLock.wait();
} catch (InterruptedException ignore) {
}
}
}
}
final String intentLaunchToken = intent.getLaunchToken();
if (aInfo.launchToken == null && intentLaunchToken != null) {
aInfo.launchToken = intentLaunchToken;
}
}
return aInfo;
}
接着回到 startActivityMayWait
方法中:
java
// base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityMayWait(......) {
//......
synchronized (mService.mGlobalLock) {
// Launcher 所在的 ActivityStack
final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Starting activity when config will change = " + stack.mConfigWillChange);
final long origId = Binder.clearCallingIdentity();
// ......
final ActivityRecord[] outRecord = new ActivityRecord[1];
// 调用另一个重载
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
//......
}
// ......
}
接着调用另一个 startActivity 重载:
java
// base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
return getExternalResult(mLastStartActivityResult);
}
对一些成员变量赋值后,接着调另一个重载 startActivity:
java
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
// 信息记录
// ActivityMetricsLogger 用于记录时间信息
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
// 参数处理
int err = ActivityManager.START_SUCCESS;
// instant app 启动相关的 bundle
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle
= options != null ? options.popAppVerificationBundle() : null;
// 获取调用者的进程信息
// WindowProcessController 是 WMS 与 AMS 通信的工具类,内部也保存了进程相关的信息
// WindowProcessController 涉及其他地方,细节暂放,先梳理流程,后面单独章节再讲
WindowProcessController callerApp = null;
if (caller != null) {
callerApp = mService.getProcessController(caller);
if (callerApp != null) {
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 = ActivityManager.START_PERMISSION_DENIED;
}
}
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);
}
// 启动目标 Activity 的 Activity
ActivityRecord sourceRecord = null;
// 目标 Activity 如果要返回数据,返回给哪个 Activity
ActivityRecord resultRecord = null;
// resultTo 指向发起端 Activity 对应的 ActivityRecord 对象中的 Token
// Token 内部有个弱引用指向 ActivityRecord,也就是说通过 Token 可以拿到 ActivityRecord
if (resultTo != null) {
// Launcher
sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Will send result to " + resultTo + " " + sourceRecord);
if (sourceRecord != null) {
// requestCode == -1
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
// 拿到启动的 flag
final int launchFlags = intent.getFlags();
//接下里就要处理各种 flag 了,一般遇到哪种看哪种
// FLAG_ACTIVITY_FORWARD_RESULT 处理,当前情景没有,省略
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
// ......
}
// 不进入
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
// ......
}
// 不进入
if (err == ActivityManager.START_SUCCESS && aInfo == null) {
// ......
}
// 不进入
if (err == ActivityManager.START_SUCCESS && sourceRecord != null
&& sourceRecord.getTaskRecord().voiceSession != null) {
// If this activity is being launched as part of a voice session, we need
// to ensure that it is safe to do so. If the upcoming activity will also
// be part of the voice session, we can only launch it if it has explicitly
// said it supports the VOICE category, or it is a part of the calling app.
if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
//......
}
}
// 不进入
if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
//......
}
// resultRecord 为 null
// 所以 resultStack 为 null
final ActivityStack resultStack = resultRecord == null
? null : resultRecord.getActivityStack();
// 不进入
if (err != START_SUCCESS) {
//......
}
// 3. 权限检测
// 当前场景,返回的 abort 为 false,表示有权限启动
// 权限和繁琐,单独一篇来分析权限
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
inTask != null, callerApp, resultRecord, resultStack);
abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
callingPid, resolvedType, aInfo.applicationInfo);
abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
callingPackage);
boolean restrictedBgActivity = false;
// 后台 Activity 启动的处理
// Android 10 开始不能直接后台启动 Activity
if (!abort) {
try {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"shouldAbortBackgroundActivityStart");
restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
originatingPendingIntent, allowBackgroundActivityStart, intent);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
// options 参数处理
// Merge the two options bundles, while realCallerOptions takes precedence.
ActivityOptions checkedOptions = options != null
? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
if (allowPendingRemoteAnimationRegistryLookup) {
checkedOptions = mService.getActivityStartController()
.getPendingRemoteAnimationRegistry()
.overrideOptionsIfNeeded(callingPackage, checkedOptions);
}
// 不进入
if (mService.mController != null) {
//......
}
// 启动过程支持添加拦截器
mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, 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;
}
// 如果权限不够,return 退出
if (abort) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
RESULT_CANCELED, null);
}
// 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 permissions need a review before any of the app components can run, we
// launch the review activity and pass a pending intent to start the activity
// we are to launching now after the review is completed.
if (aInfo != null) {
if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
// ......
}
}
// If we have an ephemeral app, abort the process of launching the resolved intent.
// Instead, launch the ephemeral installer. Once the installer is finished, it
// starts either the intent we resolved here [on install error] or the ephemeral
// app [on install success].
// 不进入
if (rInfo != null && rInfo.auxiliaryInfo != null) {
//......
}
// 创建 ActivityRecord
// 需要注意,构造函数内部 new 了一个 Token
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
if (outActivity != null) {
outActivity[0] = 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;
}
final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
// 不进入
// If we are starting an activity that is not from the same uid as the currently resumed
// one, check whether app switches are allowed.
if (voiceSession == null && (stack.getResumedActivity() == null
|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
// ......
}
mService.onStartActivitySetDidAppSwitch();
mController.doPendingActivityLaunches(false);
// 接着调另一个重载
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
return res;
}
方法很长,基本的流程如下:
- 获取到调用者的进程信息
WindowProcessController callerApp
,WindowProcessController 是 WMS 与 AMS 通信的工具类,内部也保存了进程相关的信息 - 各类权限检测
- 调用 Activity 启动过程拦截器
- new 一个 ActivityRecord
- 调用另一个重载
startActivity