Framework之AMS的启动流程
一、Instrumentation类 : 该类是一个工具类,ActivityThread接收到AMS的指令创建和调度交互都由它来执行
ActivityThread的构造方法很简单就是创建了一个ResourcesManager对象,用于管理应用程序中的资源文件
Application环境与framework-res.apk构成了Android程序的运行环境,通过Context应用程序的大管家,可以调用进程所用到的资源和方法。
StackSupervisor类是Activity启动和调度的核心类
ProcessRecord类保存一个进程的相关信息
二、AMS服务的启动过程
1.SystemServer.java的main()
public static void main(String[] args) {
new SystemServer().run(); }
2. SystemServer.java的run()
private void run() {
...
System.loadLibrary("android_servers");//1
...
mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();//3 ---------------->引导服务
startCoreServices();//4 ---------------->核心服务
startOtherServices();//5 ---------------->其他服务
}
3.SystemServer.java的startBootstrapServices
()
private void startBootstrapServices() {
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService();
我们知道SystemServiceManager的startService方法最终会返回Lifecycle类型的对象,紧接着又调用了Lifecycle的getService方法,这个方法会返回AMS类型的mService对象
mActivityManagerService.setSystemProcess();
……
mActivityManagerService.installSystemProviders();
……
mActivityManagerService.systemReady(new Runnable() {
//初始化广播的队列
mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
//初始化Service相关的容器
mServices = new ActiveServices(this);
//初始化Provider相关的Map,里面保存了注册的ContentProvider
mProviderMap = new ProviderMap(this);
//初始化并创建data/system/目录
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
....
//初始化StackSupervisor,该类是Activity启动和调度的核心类
mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
6.AMS的方法systemReady
1:在systemReady的时候初始化了deviceIdleController等对象
2:移除并杀死了那些不该在AMS之前启动的进程
3:执行了参数传入的回调函数
4:启动了Launcer界面和SystemUI
5:启动那些persistent配置为1的进程。
总结:AMS服务启动主要分为几个步骤 小米视频增加组内自动化测试
2. 调用AMS的构造方法和start方法,对AMS必要的内容进行初始化
3. 将函数AMS注册到ServiceManager中,同时对systemServer进程也创建了一个ProcessRecord对象,并设置Context的appliation为framework-res的application对象
4. 将settingsProvider加载到系统进程systemServer中
5. 调用systemReady方法做一些启动前的就绪工作,并启动了HomeActivity和SystemUI
startActivity
()public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options); …… }
public void startActivityForResult( ........) {
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, who, intent, requestCode, options);
…… }
public ActivityResult execStartActivity( .......) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
//intent做进程间传输的准备工作
intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess();
//进程间传输,最终调用到AMS服务AMS.startActivity
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); } …… }
public final int startActivity(......) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId()); }
startActivityAsUser
public final int startActivityAsUser(......) {
……
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, false, userId, null, null); }
ActivityStackSupervisor
类是Activity启动和调度的核心类
,主要管理Task和Stackfinal int startActivityMayWait(.....){
//PMS服务根据intent查询要启动的Activity B的信息,保存到ActivityInfo中
intent = new Intent(intent);
ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
……
//决定当前活动的stack
ActivityContainer container = (ActivityContainer)iContainer;
//将PMS中查询到的Activity B的信息当做参数
int res = startActivity(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, null, container, inTask);
startActivity() : 在AMS中找调用进程的processRecord信息,调用Activity的ActivityRecord信息,目标Activity还没有启动,所以需要先创建一个目标Activity的ActivityRecord信息
final int startActivityLocked(
......){ //即调用者的Activity组件
ActivityRecord sourceRecord = null;
//返回结果的Activity组件
ActivityRecord resultRecord = null;
if (resultTo != null) {
//根据resultTo Binder对象得到其指向的ActivityRecord,即Activity A的ActivityRecord信息
sourceRecord = isInAnyStackLocked(resultTo);
//一般情况下请求的Activity和要接收返回结果的Activity是同一个
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) { resultRecord = sourceRecord; } } }
//根据准备的信息,创建一个即将启动的ActivityRecord对象,即Activity B
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, this, container, options);
//将刚创建的目标Activity的ActivityRecord作为参数,继续调用startActivityUncheckedLocked(startActivity
)方法来启动
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask); (startActivity
)
这样就获取了调用者的Activity A的组件信息,和即将要启动的目标Activity B的信息。
Activity的四种不同的启动模式 默认为standard模式
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();}
ActivityStack有三个成员变量,mResumedActivity表示这个栈中处于激活状态的Activity。这个栈中处于激活状态的Acticity就是Acticity A了。
mLastPausedActivity表示上一次被暂停的Activity。
mLastPausingActivity即当前栈中正在被暂停的Activity。
mResumedActivity表示Activity A不是Null,所以调用startPasingLocked来暂停Activity A
Activity启动流程的第一部分就到此为止。总结下这部分做的主要工作
- 调用Activity的startActivity方法来启动目标Activity
- 调用Instrumentation的方法execStartActivity方法,方便Instrumentation对交互进行监测
- 以上部分是在App1的进程中执行,之后会通过进程间通信调用到AMS服务中调用AMS的startActivity方法。此时进入SystemServer进程。
- 然后由AMS中管理Acticity核心调度的类ActivityStackSupervisor的方法startActivityMayWait来处理。该方法中主要是根据Intent从PMS中查询目标Activity的信息
- ActivityStackSuperVisor的startActivityLocked方法主要是在AMS中找调用进程的processRecord信息,调用Activity的ActivityRecord信息,目标Activity还没有启动,所以需要先创建一个目标Activity的ActivityRecord信息。
- ActivityStackSuperVisor的StartActivityUncheckedLocked方法主要来处理启动模式相关的逻辑,根据不同的启动模式,找到相应的对的Task,然后又相应的Task进行处理
- ActivityStack将目标Activity加入到对应的Task顶部
- 调用ActivityStackSuperVisor的resumeTopActivityLocked方法找到处于前台的Stack,然后调用它的resumeTopActivityLocked方法激活目标Activity.
- 当前的Stack的栈开始Pasuing调用的Activity
三、暂停ActivityA的流程
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) {
//mResumeActivity代表当前激活的Activity,即Activity A
ActivityRecord prev = mResumedActivity;
……
//当前处于激活状态mResumedActivity 的设置为null
mResumedActivity = null;
//即将要处于pasuing状态的Activity 就是Activity A
mPausingActivity = prev;
mLastPausedActivity = prev;
……
try {
prev.shortComponentName, "userLeaving=" + userLeaving);
mService.updateUsageStats(prev, false);
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
2. AMS的activityPaused
public final void activityPaused(IBinder token) {
//获或Activity 所在的ActivityStack
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
//调用目标ActivityStack的activityPauseLocked方法
stack.activityPausedLocked(token, false); } }
3. ActivityStack 的activityPauseLocked
final void activityPausedLocked(IBinder token, boolean timeout) {
//根据token获取Activity A的ActivityRecord对象
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
//移除pause超时消息
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
//调用completePauseLocked方法继续执行pause逻辑
completePauseLocked(true); } ……
注解:Token代表的是Activity的binder对象,根据token可以获得Activity A的信息ActivityRecord,移除Pause超时消息,
当执行完pause逻辑的ActivityRecord和我们执行pause逻辑前的activityRecord一样的时候,即是同一个Activity,
就可以调用completePauseLocked方法来完成Activity A Pause最后的逻辑了。
startSpecificActivityLocked : 开启一个新的Activity
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
//获取目标Activity的进程ProcessRecord
ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);
……
//,由于目标Activity所在进程还没有创建,所以为空
if (app != null && app.thread != null) {
…… }
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, ……) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app; if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null;
……
startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {
.....
final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,requiredAbi, instructionSet, invokeWith, app.startTime);
String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith,new String[] {PROC_START_SEQ_IDENT + app.startSeq});
posted on 2019-07-03 10:11 zhang11111wei 阅读(1285) 评论(0) 编辑 收藏 举报