android 冷启动,android开启app过程( 二 )


解析出来的信息叫ResolveInfo,是一个容器类 , 里面包含了ActivityInfo,ServiceInfo,ProviderInfo等成员来表示四大组件的信息 , activity和broadcast信息都是用ActivityInfo来表示的 。这三个成员只有一个不为空,这里我们启动的是activity,所以ActivityInfo是不为空的 。ActivityInfo包含了各种各样的activity信息,都是声明在AndroidManifest.xml文件中的 , 比较重要的包括launchMode、theme、screenOrientation等,其中还包含了ApplicationInfo,提供packageName、targetSdkVersion等重要信息 。
额外说一句,这里的ActivityStarter.startActivityMayWait并不会等待,只有从AMS. startActivityMayWait调过来的才会真正等待activity起来,这个通常用在调试APP的启动过程 。这个时候App还没起来,我们无法选择要调试的进程,这个就可以使用startActivityMayWait,App进程起来以后,会等我们设置断点,这样就可以第一时间调试了 。命令如下:
adb shell am set-debug-app -w com.example.demo
4、创建ActivityRecord
本阶段的调用流程是:
ActivityStarter.startActivity(...)
ActivityRecord r = new ActivityRecord(callerApp,intent,aInfo,mSupervisor,...)
appToken = new Token(this, _intent);
setState(INITIALIZING, "ActivityRecord ctor");
在解析完intent以后,AMS会进一步的做各种的权限检查,包括没有找到目标组件的处理 。随后就会新建一个ActivityRecord 。ActivityRecord是AMS中保存activity信息的数据结构,AMS就是通过着一个结构来管理activity的,其主要包括的信息有:appToken、launchedFromPid、launchedFromUid、launchedFromPackage、userId、intent、componentName、requestCode、visible、taskAffinity、icon、logo、theme、processName、launchMode、fullscreen等信息 。
在其构造函数中比较重要的工作是:
1)新建了AppToken,这是activity的唯一标识
2)ActivityRecord的状态初始化为INITIALIZING
到了这一步,表明activity相关档案已被建立,接下来要做的事情就是为该activity分配任务栈 。
5、分配Task
本阶段的调用流程是:
ActivityStarter.startActivity(r,sourceRecord,true/* doResume */,...)
ActivityStarter.startActivityUnchecked(r,sourceRecord,doResume...)
ActivityRecord reusedActivity = getReusableIntentActivity()
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack)
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask...)
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,...)
startActivityUnchecked是本阶段的重点函数,需要详细分析
ActivityStarter.startActivityUnchecked(r, sourceRecord,doResume..){
//计算mLaunchFlags
computeLaunchingTaskFlags();
// 设置刚才在上面计算出来的mLaunchFlags
mIntent.setFlags(mLaunchFlags);
// 根据mLaunchFlags来查找是否有可重用的activity
ActivityRecord reusedActivity = getReusableIntentActivity();
【android 冷启动,android开启app过程】if (reusedActivity != null) {
//如果找到了可重用的activity,需要清理掉原来的信息,并把当前启动的activity的信息拷贝进去
做清理和拷贝工作...
if((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 ||
isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)){
// 没必要新建实例,回调onNewIntent并将top移至前台
deliverNewIntent(top);
}
// 计算哪个task和activity要移至前台 , 必要时会进行task的清理工作
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
}
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {