AMS--StartActivity流程整理

Activity启动流程分析:http://blog.csdn.net/luoshengyang/article/details/6689748



startActivityMayWait()函数
//根据Intent获取要启动ActivityInfo
ActivityInfo aInfo =resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
//重量级进程处理
if (aInfo != null &&(aInfo.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0)


startActivityLocked()函数
//从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了
callerApp = mService.getRecordForAppLocked(caller);

//参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中
sourceRecord = isInAnyStackLocked(resultTo);

//检查Activity启动权限
final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, callingUid);
abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,callingPid, resolvedType, aInfo.applicationInfo);

//为要启动Activity创建ActivityRecord
ActivityRecord r = new ActivityRecord

//在执行HOME appSwitch的动作时,Pending当前StartActivity动作
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,realCallingPid, realCallingUid, "Activity start")) {
  PendingActivityLaunch pal =new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
  mPendingActivityLaunches.add(pal);
  ActivityOptions.abort(options);
  return ActivityManager.START_SWITCHES_CANCELED;
}


startActivityUncheckedLocked()函数
//当intent和activity manifest存在冲突,则manifest优先
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&(launchSingleInstance || launchSingleTask)) 

//传进来的参数r.resultTo为null,表示Launcher不需要等这个即将要启动的MainActivity的执行结果
Slog.i(TAG, "startActivityUncheckedLocked r.resultTo: "+r.resultTo);

//表示并不是用户“主观意愿”启动的Activity,而是如来电、闹钟事件等触发的Activity启动
mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;

//如果调用者指示先不要Resume(DoResume为空),那么我们将delayedResume设置true.
if (!doResume) {r.delayedResume = true;}

//addingToTask 如果为true表示正在添加至某个task, 后续需要将r添加至sourceRecord所在的task
boolean addingToTask = false;
//movedHome表示是否移动home task
boolean movedHome = false;
//reuseTask 如果不为null,则表示已存在task,会重用这个task,但是这个Task里的所有Activity会被清除掉,  需要将r加入这个task 
TaskRecord reuseTask = null;    

//查找目标Activity是否有存在的Task
ActivityRecord intentActivity = !launchSingleInstance ?findTaskLocked(r) : findActivityLocked(intent, r.info);

//isLockTaskModeViolation判断当时是否为Devices owner app,如果不是就直接return,startActivity就不会启动Activity
if (isLockTaskModeViolation(intentActivity.task,
  (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
  == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
showLockTaskToast();
Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}

//为Activity创建Task
if (r.resultTo == null && inTask == null && !addingToTask&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  checkTask = new TaskRecord(mService, getNextTaskId(),
  newTaskInfo != null ? newTaskInfo : r.info,
  newTaskIntent != null ? newTaskIntent : intent,
  voiceSession, voiceInteractor);


startActivityLocked()函数5个参数
//将这个Activity放在stack的最顶层,这样才能与用户交互
task.addActivityToTop(r);
task.setFrontOfTask();
r.putInHistory();

//用于确定两个界面之间的切换使用什么样的动画效果
mWindowManager.prepareAppTransition
//在AMS中会有token记录起来了哪些Activity,就需要在对应的WMS中也做相应的添加以备案,再通过wms添加窗口时会做验证
mWindowManager.addAppToken
//设置一个APP的打开时的窗口,在APP显示第一个主界面时,需要显示一个过渡界面
mWindowManager.setAppStartingWindow


resumeTopActivityInnerLocked()函数
//top running之后的任意处于初始化状态且有显示StartingWindow, 则移除StartingWindow
cancelInitializingActivities();

//取出顶层ActivityRecord,即要启动Activity
final ActivityRecord next = topRunningActivityLocked(null);

//如果next为空,就启动Launcher。换句话说,无论何时Android系统都会有正在运行的Activity,默认就是Launcher
if (next == null) {isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);}

//如果要启动Activity与调用者是同一Activity,则什么都不做。mResumedActivity指是调用者(Launcher)
if (mResumedActivity == next && next.state == ActivityState.RESUMED &&mStackSupervisor.allResumedActivitiesComplete()) {

//处于睡眠或者关机状态,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做
if (mService.isSleepingOrShuttingDown()&& mLastPausedActivity == next&& mStackSupervisor.allPausedActivitiesComplete()) {

//拥有该activity的用户没有启动则直接返回
if (mService.mStartedUsers.get(next.userId) == null) 

//如果目标Activity正在stopping,那么就要终止它的这一操作。
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);

//如果当前正在pausing一个Activity的话,那直接返回并等待它完成
if (!mStackSupervisor.allPausedActivitiesComplete()) 

//需要等待暂停当前activity完成,再resume top activity
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;

//暂停其他Activity
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);


startPausingLocked()函数
//暂停所有子栈的Activity
if (mActivityContainer.mParentActivity == null) {mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);}

//设置状态
mResumedActivity = null;
mPausingActivity = prev;
mLastPausedActivity = prev;
prev.state = ActivityState.PAUSING;

completePauseLocked()函数
prev.stopFreezingScreenLocked(true /*force*/);
mPausingActivity = null;


pause完成后resumeTopActivityInnerLocked()函数调用
/*
*当前在堆栈顶端的Activity为我们即将要启动的Activity,这里通过调用topRunningActivityLocked将它取回来,
*保存在next变量中。之前最后一个Resumed状态的Activity,即Launcher,到了这里已经处于Paused状态了,
*因此,mResumedActivity为null。最后一个处于Paused状态的Activity为Launcher,因此,这里的mLastPausedActivity就为Launcher。
*前面我们为MainActivity创建了ActivityRecord后,它的app域一直保持为null。
*有了这些信息后,上面这段代码就容易理解了,它最终调用startSpecificActivityLocked进行下一步操作。
*/
//把即将要隐藏的Activity添加到mWaitingVisibleActivities中
if (prev != null && prev != next) {
  if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)&& next != null && !next.nowVisible) {
  mStackSupervisor.mWaitingVisibleActivities.add(prev);}


startSpecificActivityLocked()函数
//取出Activity的processRecord,应用进程第一次启动app为null
app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);

startProcessLocked()函数
//为Activity创建进程
Process.start......

realStartActivityLocked()函数
//调度启动ticks用以收集应用启动慢的信息
r.startLaunchTickingLocked();
//更新Configuration
if (checkConfig) {
Configuration config = mWindowManager.updateOrientationFromAppTokens(
  mService.mConfiguration,
  r.mayFreezeScreenLocked(app) ? r.appToken : null);
if (config != null) {
r.frozenBeforeDestroy = true;
}
mService.updateConfigurationLocked(config, r, false, false);
}
updateLruProcessLocked
Android所有应用进程(包括system_server)的ProcessRecord信息都保存在mPidsSelfLocked成员中,除此之外还有一个成员变量mLruProcesses也用于保存ProcessRecord。mLruProcesses的类型虽然是ArrayList,但其内部成员却是按照ProcessRecord的lruWeight大小排序的。在运行过程中,AMS会根据lruWeight的变化调整mLruProcesses成员的位置。updateLruProcessLocked的主要工作是根据app的lruWeight值调整它在数组中的位置。lruWeight越大,其在数组中的位置就越靠后。如果该app和某些Service或ContentProvider有交互关系,那就连同这些Service或ContentProvider所在进程调节lruWeight值。

updateOomAdjLocked
在updateOomAdjLocked函数中,AMS做了比较多事,都是为了最终调用computeOomAdjLocked函数计算某个进程的oom_adj和调度策略来完成对应用进程的管理,这之间4.0增加了一个接口类ComponentCallbacks2,定义了一个函数onTrimMemory,主要通知应用进程进行一定的内存释放。AMS的进程管理核心还是在computeOomAdjLocked里,computeOomAdjLocked就是一个算法,就是根据各种情况来设置几个值,这个调整的算法改进变动的可能性还是比较大的。
//如果当前启动Activity为固定屏幕,则设置它的task为固定屏幕任务
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
}
//将该进程设置为前台进程PROCESS_STATE_TOP
app.forceProcessStateUpTo(mService.mTopProcessState);


handleLaunchActivity()函数
//执行onCreate
Activity a = performLaunchActivity(r, customIntent);
//执行onResume
handleResumeActivity(r.token, false, r.isForward,r.reasonFlags,!r.activity.mFinished && !r.startsNotResumed);


















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值