0x01
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
最终走到
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options)
分两种情况
1mParent
2mParent!=null
mParent = null 的情况最后分析
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options)
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), 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;
这段代码主要用途是为启动一个activity准备参数,下面说说所准备的参数
1whoThread
是一个IApplicationThread的对象,这个对象是ActivityThread的代理,AMS通过这个对象同ActivityThread通信,
2 调用这packagName
3 intent
4 type (provider.getType返回的信息)
5 token
该ActivityRecord的客户端
6requestCode
接下来就调用到AMS里面了
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
这个函数会先检查调用者uid是否可以执行启动Activity.如果该uid>99000&&uid<99999 则不允许启动activity,具体为什么这么划分还不清楚,应该和多用户有关
检查多用户的userid是否可以启动这个activity,比如有些多用户不能启动浏览器等
ActivityStarter->final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
检查intent中包含文件描述符,抛出异常
通过PMS解析Intent,返回ResolveInfo信息
通过ResolveInfo解析ActivityInfo
ActivityStarter->final int startActivityLocked(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,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
获取调用者App的ProcessRecord
找到接受结果的activity的ActivityRecord(如果有)
这里创建两个变量sourceRecord 和ResultRecord分别代调用这activityrecord和接受结果的 一般这二者为同一个,如果不接收结果result可能为空,如果设置了FLAG_ACTIVITY_FORWARD_RESULT,则二者不同
检查权限
PERMISSIONS_REVIEW_REQUIRED 相关的逻辑 弹出中间界面
ephemeralResolveInfo状态的任务,(可能是正在安装的程序,被替换后要重新启动该界面)
ActivityStarter->private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
计算启动flags
private void computeLaunchingTaskFlags() {
计算stack
private void computeSourceStack() {
如果掉启的activity finish了,则添加NEW_TASK