启动Activity有多种方式,简单记录下在Launcher下点击应用图表启动Activity的流程。
以启动Setting为例,通过跟踪Launcher.java的onclick事件,发现最终通过ActivityManagerNative.getDefault()获取ActivityManager的代理对象,然后调用startActivity()方法调用到ActivityManagerService中的startActivity()方法。继续跟踪,调用到ActivityStackSupervisor中的startActivityMayWait()方法。
- 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, WaitResult outResult, Configuration config,
- Bundle options, int userId, IActivityContainer iContainer, TaskRecord inTask) {
- // Refuse possible leaked file descriptors
- if (intent != null && intent.hasFileDescriptors()) {
- throw new IllegalArgumentException("File descriptors passed in Intent");
- }
- boolean componentSpecified = intent.getComponent() != null;//true
- // Don't modify the client's object!
- intent = new Intent(intent);//new一个Intent,不改变原始Intent.
- // Collect information about the target of the Intent.
- ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
- profilerInfo, userId);//通过PackageManager查询对应的ActivityInfo.
- ActivityContainer container = (ActivityContainer)iContainer;
- synchronized (mService) {
- //判断启动此Activity的pid与uid
- final int realCallingPid = Binder.getCallingPid();
- final int realCallingUid = Binder.getCallingUid();
- int callingPid;
- if (callingUid >= 0) {
- callingPid = -1;
- } else if (caller == null) {
- callingPid = realCallingPid;
- callingUid = realCallingUid;
- } else {
- callingPid = callingUid = -1;
- }
- final ActivityStack stack;
- if (container == null || container.mStack.isOnHomeDisplay()) {
- stack = getFocusedStack();
- } else {
- stack = container.mStack;
- }
- stack.mConfigWillChange = config != null
- && mService.mConfiguration.diff(config) != 0;
- final long origId = Binder.clearCallingIdentity();
- if (aInfo != null &&
- (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
- //不满足此条件
- ''''''
- }
- //调用到startActivityLocked()方法。
- int res = startActivityLocked(caller, intent, resolvedType, aInfo,
- voiceSession, voiceInteractor, resultTo, resultWho,
- requestCode, callingPid, callingUid, callingPackage,
- realCallingPid, realCallingUid, startFlags, options,
- componentSpecified, null, container, inTask);
- Binder.restoreCallingIdentity(origId);
- //没有回调
- if (outResult != null) {
- ''''''
- }
- return res;
- }
- }
startActivityMayWait的主要作用就是查询对应的ActivityInfo,获取callingPid与callingUid,然后转交给startActivityLocked()方法。
- final int startActivityLocked(IApplicationThread caller,
- Intent intent, String resolvedType, ActivityInfo aInfo,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- IBinder resultTo, String resultWho, int requestCode,
- int callingPid, int callingUid, String callingPackage,
- int realCallingPid, int realCallingUid, int startFlags, Bundle options,
- boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
- TaskRecord inTask) {
- int err = ActivityManager.START_SUCCESS;
- ProcessRecord callerApp = null;
- if (caller != null) {
- //获取caller对应的ProcessRecord
- callerApp = mService.getRecordForAppLocked(caller);
- if (callerApp != null) {
- callingPid = callerApp.pid;
- callingUid = callerApp.info.uid;
- } else {
- Slog.w(TAG, "Unable to find app for caller " + caller
- + " (pid=" + callingPid + ") when starting: "
- + intent.toString());
- err = ActivityManager.START_PERMISSION_DENIED;
- }
- }
- ActivityRecord sourceRecord = null;
- ActivityRecord resultRecord = null;
- if (resultTo != null) {//resultTo代表Launcher
- sourceRecord = isInAnyStackLocked(resultTo);
- if (DEBUG_RESULTS) Slog.v(
- TAG, "Will send result to " + resultTo + " " + sourceRecord);
- if (sourceRecord != null) {
- //requestCode 为-1,不需要返回结果。
- if (requestCode >= 0 && !sourceRecord.finishing) {
- resultRecord = sourceRecord;
- }
- }
- }
- final int launchFlags = intent.getFlags();
- ......
- final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;//resultStack为空。
- //检查是否有启动权限。
- final int startAnyPerm = mService.checkPermission(
- START_ANY_ACTIVITY, callingPid, callingUid);
- final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
- callingUid, aInfo.applicationInfo.uid, aInfo.exported);
- if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
- if (resultRecord != null) {
- resultStack.sendActivityResultLocked(-1,
- resultRecord, resultWho, requestCode,
- Activity.RESULT_CANCELED, null);
- }
- String msg;
- if (!aInfo.exported) {
- msg = "Permission Denial: starting " + intent.toString()
- + " from " + callerApp + " (pid=" + callingPid
- + ", uid=" + callingUid + ")"
- + " not exported from uid " + aInfo.applicationInfo.uid;
- } else {
- msg = "Permission Denial: starting " + intent.toString()
- + " from " + callerApp + " (pid=" + callingPid
- + ", uid=" + callingUid + ")"
- + " requires " + aInfo.permission;
- }
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
- }
- boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
- callingPid, resolvedType, aInfo.applicationInfo);
- ......
- //创建对应的ActivityRecord
- ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
- intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
- requestCode, componentSpecified, this, container, options);
- if (outActivity != null) {
- outActivity[0] = r;
- }
- final ActivityStack stack = getFocusedStack();
- ......
- doPendingActivityLaunchesLocked(false);
- //调用startActivityUncheckedLocked()方法。
- err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
- startFlags, true, options, inTask);
- if (err < 0) {
- // If someone asked to have the keyguard dismissed on the next
- // activity start, but we are not actually doing an activity
- // switch... just dismiss the keyguard now, because we
- // probably want to see whatever is behind it.
- notifyActivityDrawnForKeyguard();
- }
- return err;
- }
startActivityLocked的主要作用:获取caller的ProcessRecord,检查是否需要返回结果,检查各种flag标记,检查caller是否有启动权限,创建对应的ActivityRecord,最后转到startActivityUncheckedLocked()方法。
- final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
- boolean doResume, Bundle options, TaskRecord inTask) {
- final Intent intent = r.intent;
- final int callingUid = r.launchedFromUid;
- // In some flows in to this function, we retrieve the task record and hold on to it
- // without a lock before calling back in to here... so the task at this point may
- // not actually be in recents. Check for that, and if it isn't in recents just
- // consider it invalid.
- if (inTask != null && !inTask.inRecents) {
- Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
- inTask = null;
- }
- //检查启动模式
- final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
- final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
- final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
- int launchFlags = intent.getFlags();
- if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
- ......
- } else {
- switch (r.info.documentLaunchMode) {
- case ActivityInfo.DOCUMENT_LAUNCH_NONE:
- break;
- case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
- launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
- break;
- case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
- launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
- break;
- case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
- launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
- break;
- }
- }
- final boolean launchTaskBehind = r.mLaunchTaskBehind
- && !launchSingleTask && !launchSingleInstance
- && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
- //resultTo为空
- if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
- ......
- }
- if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
- launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
- }
- // If we are actually going to launch in to a new task, there are some cases where
- // we further want to do multiple task.
- if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
- if (launchTaskBehind
- || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
- launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
- }
- }
- // We'll invoke onUserLeaving before onPause only if the launching
- // activity did not explicitly state that this is an automated launch.
- mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
- // If the caller has asked not to resume at this point, we make note
- // of this in the record so that we can skip it when trying to find
- // the top running activity.
- if (!doResume) {
- r.delayedResume = true;
- }
- ActivityRecord notTop =
- (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
- if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
- ActivityRecord checkedCaller = sourceRecord;
- if (checkedCaller == null) {
- checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
- }
- if (!checkedCaller.realActivity.equals(r.realActivity)) {
- // Caller is not the same as launcher, so always needed.
- startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
- }
- }
- //上边主要是通过启动模式跟flag来确定actiivty是否需要运行于新的task
- boolean addingToTask = false;
- TaskRecord reuseTask = null;
- // If the caller is not coming from another activity, but has given us an
- // explicit task into which they would like us to launch the new activity,
- // then let's see about doing that.
- if (sourceRecord == null && inTask != null && inTask.stack != null) {
- //不满足此条件
- } else {
- inTask = null;
- }
- if (inTask == null) {
- if (sourceRecord == null) {//sourceRecord不为空
- // This activity is not being started from another... in this
- // case we -always- start a new task.
- if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
- Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
- "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
- launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
- }
- } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
- // The original activity who is starting us is running as a single
- // instance... this new activity it is starting must go on its
- // own task.
- launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
- } else if (launchSingleInstance || launchSingleTask) {
- // The activity being started is a single instance... it always
- // gets launched into its own task.
- launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
- }
- }
- ActivityInfo newTaskInfo = null;
- Intent newTaskIntent = null;
- ActivityStack sourceStack;
- if (sourceRecord != null) {
- if (sourceRecord.finishing) {
- // If the source is finishing, we can't further count it as our source. This
- // is because the task it is associated with may now be empty and on its way out,
- // so we don't want to blindly throw it in to that task. Instead we will take
- // the NEW_TASK flow and try to find a task for it. But save the task information
- // so it can be used when creating the new task.
- if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
- Slog.w(TAG, "startActivity called from finishing " + sourceRecord
- + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
- launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
- newTaskInfo = sourceRecord.info;
- newTaskIntent = sourceRecord.task.intent;
- }
- sourceRecord = null;
- sourceStack = null;
- } else {
- sourceStack = sourceRecord.task.stack;
- }
- } else {
- sourceStack = null;
- }
- boolean movedHome = false;
- ActivityStack targetStack;
- intent.setFlags(launchFlags);
- // We may want to try to place the new activity in to an existing task. We always
- // do this if the target activity is singleTask or singleInstance; we will also do
- // this if NEW_TASK has been requested, and there is not an additional qualifier telling
- // us to still place it in a new task: multi task, always doc mode, or being asked to
- // launch this as a new task behind the current one.
- if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
- (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
- || launchSingleInstance || launchSingleTask) {//满足此条件
- // If bring to front is requested, and no result is requested and we have not
- // been given an explicit task to launch in to, and
- // we can find a task that was started with this same
- // component, then instead of launching bring that one to the front.
- if (inTask == null && r.resultTo == null) {//满足
- // See if there is a task to bring to the front. If this is
- // a SINGLE_INSTANCE activity, there can be one and only one
- // instance of it in the history, and it is always in its own
- // unique task, so we do a special search.
- //检查是否有可复用的Task及Activity。
- ActivityRecord intentActivity = !launchSingleInstance ?
- findTaskLocked(r) : findActivityLocked(intent, r.info);
- //本例为第一次启动,所以intentActivity为空。
- if (intentActivity != null) {
- ......
- }
- }
- if (r.packageName != null) {
- // If the activity being launched is the same as the one currently
- // at the top, then we need to check if it should only be launched
- // once.
- ActivityStack topStack = getFocusedStack();
- //top为Launcher
- ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
- if (top != null && r.resultTo == null) {//满足
- //检测是否可复用Activity,top为Launcher,r为Setting,不满足
- if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
- if (top.app != null && top.app.thread != null) {
- if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
- || launchSingleTop || launchSingleTask) {
- ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
- top.task);
- // For paranoia, make sure we have correctly
- // resumed the top activity.
- topStack.mLastPausedActivity = null;
- if (doResume) {
- resumeTopActivitiesLocked();
- }
- ActivityOptions.abort(options);
- if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
- // We don't need to start a new activity, and
- // the client said not to do anything if that
- // is the case, so this is it!
- return ActivityManager.START_RETURN_INTENT_TO_CALLER;
- }
- top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
- return ActivityManager.START_DELIVERED_TO_TOP;
- }
- }
- }
- }
- } else {
- .....
- }
- boolean newTask = false;
- boolean keepCurTransition = false;
- TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
- sourceRecord.task : null;
- // Should this be considered a new task?
- if (r.resultTo == null && inTask == null && !addingToTask
- && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {//满足
- if (isLockTaskModeViolation(reuseTask)) {
- Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
- return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
- }
- newTask = true;
- targetStack = adjustStackFocus(r, newTask);
- if (!launchTaskBehind) {
- targetStack.moveToFront("startingNewTask");
- }
- if (reuseTask == null) {
- //ActivityRecord与TaskRecord相关连。
- //getNextTaskId()方法更新Task数量
- r.setTask(targetStack.createTaskRecord(getNextTaskId(),
- newTaskInfo != null ? newTaskInfo : r.info,
- newTaskIntent != null ? newTaskIntent : intent,
- voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
- taskToAffiliate);
- } else {
- r.setTask(reuseTask, taskToAffiliate);
- }
- if (!movedHome) {
- if ((launchFlags &
- (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
- == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
- // Caller wants to appear on home activity, so before starting
- // their own activity we will bring home to the front.
- r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
- }
- }
- } else if (sourceRecord != null) {
- ......
- } else if (inTask != null) {
- ......
- } else {
- ......
- }
- //权限相关
- mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
- intent, r.getUriPermissionsLocked(), r.userId);
- if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
- r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
- }
- if (newTask) {
- EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
- }
- ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
- targetStack.mLastPausedActivity = null;
- //转到startActivityLocked()方法。
- targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
- if (!launchTaskBehind) {
- // Don't set focus on an activity that's going to the back.
- mService.setFocusedActivityLocked(r, "startedActivity");
- }
- return ActivityManager.START_SUCCESS;
- }
startActivityUncheckedLocked主要功能:根据启动模式和启动标记,判断是否需要在新的Task中启动Activity。判断是否有可复用的Task或Activity。将ActivityRecord与TaskRecord关连,更新Task数量,调用startActivityLocked()方法。
- final void startActivityLocked(ActivityRecord r, boolean newTask,
- boolean doResume, boolean keepCurTransition, Bundle options) {
- TaskRecord rTask = r.task;
- final int taskId = rTask.taskId;
- // mLaunchTaskBehind tasks get placed at the back of the task stack.
- if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
- // Last activity in task had been removed or ActivityManagerService is reusing task.
- // Insert or replace.
- // Might not even be in.
- insertTaskAtTop(rTask);
- mWindowManager.moveTaskToTop(taskId);
- }
- TaskRecord task = null;
- if (!newTask) {//本例中newTask为true。
- // If starting in an existing task, find where that is...
- boolean startIt = true;
- for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- task = mTaskHistory.get(taskNdx);
- if (task.getTopActivity() == null) {
- // All activities in task are finishing.
- continue;
- }
- if (task == r.task) {
- // Here it is! Now, if this is not yet visible to the
- // user, then just add it without starting; it will
- // get started when the user navigates back to it.
- if (!startIt) {
- if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
- + task, new RuntimeException("here").fillInStackTrace());
- task.addActivityToTop(r);
- r.putInHistory();
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
- r.userId, r.info.configChanges, task.voiceSession != null,
- r.mLaunchTaskBehind);
- if (VALIDATE_TOKENS) {
- validateAppTokensLocked();
- }
- ActivityOptions.abort(options);
- return;
- }
- break;
- } else if (task.numFullscreen > 0) {
- startIt = false;
- }
- }
- }
- ......
- task = r.task;
- task.addActivityToTop(r);//将Setting对应的ActivityRecord放到栈顶。
- task.setFrontOfTask();
- r.putInHistory();
- if (!isHomeStack() || numActivities() > 0) {
- // We want to show the starting preview window if we are
- // switching to a new task, or the next activity's process is
- // not currently running.
- boolean showStartingIcon = newTask;
- ProcessRecord proc = r.app;
- if (proc == null) {
- proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
- }
- if (proc == null || proc.thread == null) {
- showStartingIcon = true;
- }
- if (DEBUG_TRANSITION) Slog.v(TAG,
- "Prepare open transition: starting " + r);
- if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
- mNoAnimActivities.add(r);
- } else {
- mWindowManager.prepareAppTransition(newTask
- ? r.mLaunchTaskBehind
- ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
- : AppTransition.TRANSIT_TASK_OPEN
- : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
- mNoAnimActivities.remove(r);
- }
- mWindowManager.addAppToken(task.mActivities.indexOf(r),
- r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
- r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
- boolean doShow = true;
- if (newTask) {
- // Even though this activity is starting fresh, we still need
- // to reset it to make sure we apply affinities to move any
- // existing activities from other tasks in to it.
- // If the caller has requested that the target task be
- // reset, then do so.
- if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
- resetTaskIfNeededLocked(r, r);
- doShow = topRunningNonDelayedActivityLocked(null) == r;
- }
- } else if (options != null && new ActivityOptions(options).getAnimationType()
- == ActivityOptions.ANIM_SCENE_TRANSITION) {
- doShow = false;
- }
- if (r.mLaunchTaskBehind) {
- // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
- // tell WindowManager that r is visible even though it is at the back of the stack.
- mWindowManager.setAppVisibility(r.appToken, true);
- ensureActivitiesVisibleLocked(null, 0);
- } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
- // Figure out if we are transitioning from another activity that is
- // "has the same starting icon" as the next one. This allows the
- // window manager to keep the previous window it had previously
- // created, if it still had one.
- ActivityRecord prev = mResumedActivity;
- if (prev != null) {
- // We don't want to reuse the previous starting preview if:
- // (1) The current activity is in a different task.
- if (prev.task != r.task) {
- prev = null;
- }
- // (2) The current activity is already displayed.
- else if (prev.nowVisible) {
- prev = null;
- }
- }
- mWindowManager.setAppStartingWindow(
- r.appToken, r.packageName, r.theme,
- mService.compatibilityInfoForPackageLocked(
- r.info.applicationInfo), r.nonLocalizedLabel,
- r.labelRes, r.icon, r.logo, r.windowFlags,
- prev != null ? prev.appToken : null, showStartingIcon);
- r.mStartingWindowShown = true;
- }
- } else {
- // If this is the first activity, don't do any fancy animations,
- // because there is nothing for it to animate on top of.
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,
- r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
- ActivityOptions.abort(options);
- options = null;
- }
- if (VALIDATE_TOKENS) {
- validateAppTokensLocked();
- }
- if (doResume) {
- mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
- }
- }
startActivityLocked主要功能:根据newTask判断是否复用task,将ActivityRecord放入栈顶,准备Activity切换动画,调用resumeTopActivitiesLocked()方法。
- boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
- Bundle targetOptions) {
- if (targetStack == null) {
- targetStack = getFocusedStack();
- }
- // Do targetStack first.
- boolean result = false;
- if (isFrontStack(targetStack)) {//调用到ActivityStack的resumeTopActivityLocked()方法。本例中target为Setting
- result = targetStack.resumeTopActivityLocked(target, targetOptions);
- }
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- if (stack == targetStack) {
- // Already started above.
- continue;
- }
- if (isFrontStack(stack)) {
- stack.resumeTopActivityLocked(null);
- }
- }
- }
- return result;
- }
resumeTopActivitiesLocked中继续调用了ActivityStack的resumeTopActivityLocked()方法,resumeTopActivityLocked()中又调用了resumeTopActivityInnerLocked()方法。
- final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
- if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
- //判断ActivityManagerService是否在启动阶段
- if (!mService.mBooting && !mService.mBooted) {
- // Not ready yet!
- return false;
- }
- // Find the first activity that is not finishing.
- //获取栈顶Activity,之前已经把对应的ActivityRecord放入栈顶,本例为Settings。
- final ActivityRecord next = topRunningActivityLocked(null);
- // Remember how we'll process this pause/resume situation, and ensure
- // that the state is reset however we wind up proceeding.
- final boolean userLeaving = mStackSupervisor.mUserLeaving;
- mStackSupervisor.mUserLeaving = false;
- final TaskRecord prevTask = prev != null ? prev.task : null;
- //如果next为空,启动Launcher。
- if (next == null) {
- // There are no more activities! Let's just start up the
- // Launcher...
- ActivityOptions.abort(options);
- // Only resume home if on home display
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");
- }
- next.delayedResume = false;
- // If the top activity is the resumed one, nothing to do.
- // mResumedActivity为Launcher,next为Settings
- if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
- mStackSupervisor.allResumedActivitiesComplete()) {
- ......
- }
- final TaskRecord nextTask = next.task;
- ......
- // The activity may be waiting for stop, but that is no longer
- // appropriate for it.
- //mStoppingActivities移除对应的ActivityRecord
- mStackSupervisor.mStoppingActivities.remove(next);
- mStackSupervisor.mGoingToSleepActivities.remove(next);
- next.sleeping = false;
- mStackSupervisor.mWaitingVisibleActivities.remove(next);
- // If we are currently pausing an activity, then don't do anything
- // until that is done.
- ......
- // We need to start pausing the current activity so the top one
- // can be resumed...
- boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
- boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
- //mResumedActivity此时为Launcher
- if (mResumedActivity != null) {
- //调用startPausingLocked去暂停
- pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
- }
- //暂停成功为true
- if (pausing) {
- // At this point we want to put the upcoming activity's process
- // at the top of the LRU list, since we know we will be needing it
- // very soon and it would be a waste to let it get killed if it
- // happens to be sitting towards the end.
- if (next.app != null && next.app.thread != null) {
- mService.updateLruProcessLocked(next.app, true, null);
- }
- if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
- return true;
- }
- //后续省略,此次不会进入后续步骤,之后还会进入这个方法。
- ......
- }
resumeTopActivityInnerLocked主要功能:判断next是否为空,mStoppingActivities移除对应的ActivityRecord,调用startPausingLocked()方法,去暂停mResumedActivity对应的Activity,本例为Launcher。
- final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
- boolean dontWait) {
- if (mPausingActivity != null) {
- Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity);
- completePauseLocked(false);
- }
- //将prev赋值为Launcher的ActivityRecord。
- ActivityRecord prev = mResumedActivity;
- if (prev == null) {
- ......
- }
- //置空mResumedActivity,mPausingActivity、mLastPausedActivity赋值为Launcher的ActivityRecord。
- mResumedActivity = null;
- mPausingActivity = prev;
- mLastPausedActivity = prev;
- mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
- || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
- prev.state = ActivityState.PAUSING;//Launcher状态改为PAUSING。
- prev.task.touchActiveTime();
- clearLaunchTime(prev);
- final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
- if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
- prev.updateThumbnailLocked(screenshotActivities(prev), null);
- }
- stopFullyDrawnTraceIfNeeded();
- mService.updateCpuStats();
- if (prev.app != null && prev.app.thread != null) {
- try {
- EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
- prev.userId, System.identityHashCode(prev),
- prev.shortComponentName);
- mService.updateUsageStats(prev, false);
- //调度schedulePauseActivity方法
- prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
- userLeaving, prev.configChangeFlags, dontWait);
- } catch (Exception e) {
- }
- } else {
- mPausingActivity = null;
- mLastPausedActivity = null;
- mLastNoHistoryActivity = null;
- }
- if (mPausingActivity != null) {
- if (!uiSleeping) {//在新Activity启动之前,暂停key dispatch事件。
- prev.pauseKeyDispatchingLocked();
- } else {
- }
- if (dontWait) {//本例为false
- completePauseLocked(false);
- return false;
- } else {
- // 暂停超时处理
- Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
- msg.obj = prev;
- prev.pauseTime = SystemClock.uptimeMillis();
- mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
- return true;
- }
- } else {
- // This activity failed to schedule the
- // pause, so just treat it as being paused now.
- if (!resuming) {
- mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
- }
- return false;
- }
- }
startPausingLocked方法主要功能:置空mResumedActivity,记录要暂停的Activity,调度Activity暂停方法的生命周期,暂停超时处理。下面分析schedulePauseActivity方法。
ActivityStack与当前要暂停的Activity处于不同的进程中,因此需要通过当前的Activity的ProcessRecord的IApplicationThread的代理类,通过代理对象访问主线程定义的ActivityThread,进而调用到ActivityThread暂停Activity。
/frameworks/base/core/java/android/app/ActivityThread.java
- public final void schedulePauseActivity(IBinder token, boolean finished,
- boolean userLeaving, int configChanges, boolean dontReport) {
- //通过消息机制发送
- sendMessage(
- finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
- token,
- (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
- configChanges);
- }
找到handleMessage对应的case:PAUSE_ACTIVITY,调用了handlePauseActivity()方法。
- private void handlePauseActivity(IBinder token, boolean finished,
- boolean userLeaving, int configChanges, boolean dontReport) {
- ActivityClientRecord r = mActivities.get(token);//token代表Launcher信息
- if (r != null) {
- if (userLeaving) {
- performUserLeavingActivity(r);//调用onUserInteraction和onUserLeaveHint方法。
- }
- r.activity.mConfigChangeFlags |= configChanges;
- //调用暂停的生命周期
- performPauseActivity(token, finished, r.isPreHoneycomb());
- // Make sure any pending writes are now committed.
- if (r.isPreHoneycomb()) {
- QueuedWork.waitToFinish();
- }
- // Tell the activity manager we have paused.
- if (!dontReport) {
- try {//通知ActivityManagerService暂停完毕。
- ActivityManagerNative.getDefault().activityPaused(token);
- } catch (RemoteException ex) {
- }
- }
- mSomeActivitiesChanged = true;
- }
- }
- final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
- boolean saveState) {
- if (r.paused) {
- if (r.activity.mFinished) {
- return null;
- }
- ......
- }
- if (finished) {
- r.activity.mFinished = true;
- }
- try {
- // Next have the activity save its current state and managed dialogs...
- if (!r.activity.mFinished && saveState) {
- callCallActivityOnSaveInstanceState(r);//调用Activity生命周期的onSaveInstanceState方法。
- }
- // Now we are idle.
- r.activity.mCalled = false;
- mInstrumentation.callActivityOnPause(r.activity);//调用Activity生命周期onPause方法。
- EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
- r.activity.getComponentName().getClassName());
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString() +
- " did not call through to super.onPause()");
- }
- } catch (SuperNotCalledException e) {
- throw e;
- } catch (Exception e) {
- }
- }
- r.paused = true;
- // Notify any outstanding on paused listeners
- ArrayList<OnActivityPausedListener> listeners;
- synchronized (mOnPauseListeners) {
- listeners = mOnPauseListeners.remove(r.activity);
- }
- int size = (listeners != null ? listeners.size() : 0);
- for (int i = 0; i < size; i++) {
- listeners.get(i).onPaused(r.activity);
- }
- return !r.activity.mFinished && saveState ? r.state : null;
- }
执行完onPause方法后,会通知ActivityManagerService,执行activityPausedactivityPaused方法。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- public final void activityPaused(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- synchronized(this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- stack.activityPausedLocked(token, false);//调用ActivityStack中activityPausedLocked()方法。
- }
- }
- Binder.restoreCallingIdentity(origId);
- }
- final void activityPausedLocked(IBinder token, boolean timeout) {
- final ActivityRecord r = isInStackLocked(token);
- if (r != null) {//移除超时处理消息
- mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
- if (mPausingActivity == r) {
- //调用completePauseLocked()方法。
- completePauseLocked(true);
- } else {
- ......
- }
- }
- }
activityPausedLocked主要就是移除之前的暂停超时处理消息,并且去掉用completePauseLocked方法,进行下一步操作。
- private void completePauseLocked(boolean resumeNext) {
- ActivityRecord prev = mPausingActivity;
- //prev本例为Launcher的ActivityRecord。
- if (prev != null) {
- prev.state = ActivityState.PAUSED;//状态改为PAUSED。
- if (prev.finishing) {
- prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
- } else if (prev.app != null) {
- if (prev.waitingVisible) {
- prev.waitingVisible = false;
- mStackSupervisor.mWaitingVisibleActivities.remove(prev);
- if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
- TAG, "Complete pause, no longer waiting: " + prev);
- }
- if (prev.configDestroy) {
- destroyActivityLocked(prev, true, "pause-config");
- } else if (!hasVisibleBehindActivity()) {
- //加入到mStoppingActivities列表中
- mStackSupervisor.mStoppingActivities.add(prev);
- if (mStackSupervisor.mStoppingActivities.size() > 3 ||
- prev.frontOfTask && mTaskHistory.size() <= 1) {
- mStackSupervisor.scheduleIdleLocked();//由scheduleIdleLocked处理stop。
- } else {
- mStackSupervisor.checkReadyForSleepLocked();
- }
- }
- } else {
- prev = null;
- }
- mPausingActivity = null;//以处理pause操作,置空。
- }
- if (resumeNext) {//true
- final ActivityStack topStack = mStackSupervisor.getFocusedStack();
- if (!mService.isSleepingOrShuttingDown()) {//满足
- mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);//调用resumeTopActivitiesLocked,本例中prev仍是Launcher。
- } else {
- mStackSupervisor.checkReadyForSleepLocked();
- ActivityRecord top = topStack.topRunningActivityLocked(null);
- if (top == null || (prev != null && top != prev)) {
- mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
- }
- }
- }
- if (prev != null) {
- prev.resumeKeyDispatchingLocked();
- ......
- }
completePauseLocked主要功能:将要暂停的Activity状态更改为PAUSED,将mPausingActivity置为空,调用resumeTopActivitiesLocked方法,resumeTopActivitiesLocked方法内部会调用到resumeTopActivityInnerLocked()方法。此时为第二次调用此方法。
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
- final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
- if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
- //这是第二次进入到这个方法里,省略第一次进来代码
- ......
- if (mService.isSleeping() && mLastNoHistoryActivity != null &&
- !mLastNoHistoryActivity.finishing) {
- requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
- null, "no-history", false);
- mLastNoHistoryActivity = null;
- }
- if (prev != null && prev != next) {
- if (!prev.waitingVisible && next != null && !next.nowVisible) {
- prev.waitingVisible = true;
- mStackSupervisor.mWaitingVisibleActivities.add(prev);
- if (DEBUG_SWITCH) Slog.v(
- TAG, "Resuming top, waiting visible to hide: " + prev);
- } else {
- if (prev.finishing) {
- mWindowManager.setAppVisibility(prev.appToken, false);
- } else {//满足else
- ......//打印log
- }
- }
- }
- // Launching this app's activity, make sure the app is no longer
- // considered stopped.
- try {//确保应用非stop状态。
- AppGlobals.getPackageManager().setPackageStoppedState(
- next.packageName, false, next.userId); /* TODO: Verify if correct userid */
- } catch (RemoteException e1) {
- } catch (IllegalArgumentException e) {
- }
- // We are starting up the next activity, so tell the window manager
- // that the previous one will be hidden soon. This way it can know
- // to ignore it when computing the desired screen orientation.
- boolean anim = true;
- if (prev != null) {
- if (prev.finishing) {
- ......
- } else {
- //准备切换动画。
- if (mNoAnimActivities.contains(next)) {
- anim = false;
- mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
- } else {
- mWindowManager.prepareAppTransition(prev.task == next.task
- ? AppTransition.TRANSIT_ACTIVITY_OPEN
- : next.mLaunchTaskBehind
- ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
- : AppTransition.TRANSIT_TASK_OPEN, false);
- }
- }
- }
- } else {
- ......
- }
- Bundle resumeAnimOptions = null;
- if (anim) {
- ActivityOptions opts = next.getOptionsForTargetActivityLocked();
- if (opts != null) {
- resumeAnimOptions = opts.toBundle();
- }
- next.applyOptionsLocked();
- } else {
- next.clearOptionsLocked();
- }
- ActivityStack lastStack = mStackSupervisor.getLastStack();
- //next.app为要启动的activity的ProcessRecord,此为第一次启动,故为空
- if (next.app != null && next.app.thread != null) {
- ......
- } else {
- // Whoops, need to restart this activity!
- if (!next.hasBeenLaunched) {
- next.hasBeenLaunched = true;
- } else {
- if (SHOW_APP_STARTING_PREVIEW) {//切换动画
- mWindowManager.setAppStartingWindow(
- next.appToken, next.packageName, next.theme,
- mService.compatibilityInfoForPackageLocked(
- next.info.applicationInfo),
- next.nonLocalizedLabel,
- next.labelRes, next.icon, next.logo, next.windowFlags,
- null, true);
- }
- }//调用startSpecificActivityLocked()方法。
- mStackSupervisor.startSpecificActivityLocked(next, true, true);
- }
- if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
- return true;
- }
resumeTopActivityInnerLocked第二次调用,跳过执行第一次进入时的代码。与第一次进入最大区别就是:此时mResumedActivity为null,即Launcher已经进入暂停状态。接下来看startSpecificActivityLocked()方法。
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
- void startSpecificActivityLocked(ActivityRecord r,
- boolean andResume, boolean checkConfig) {
- // Is this activity's application already running?
- //第一次进入,此时ProcessRecord为null
- ProcessRecord app = mService.getProcessRecordLocked(r.processName,
- r.info.applicationInfo.uid, true);
- r.task.stack.setLaunchTime(r);
- if (app != null && app.thread != null) {
- ......
- }
- mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
- "activity", r.intent.getComponent(), false, false, true);
- }
startSpecificActivityLocked方法,查询ProcessRecord,调用startProcessLocked()方法。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
- boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
- boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
- String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
- long startTime = SystemClock.elapsedRealtime();
- ProcessRecord app;
- if (!isolated) {
- app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
- checkTime(startTime, "startProcess: after getProcessRecord");
- } else {
- app = null;
- }
- if (app != null && app.pid > 0) {
- ......//app为null
- }
- String hostingNameStr = hostingName != null
- ? hostingName.flattenToShortString() : null;
- ......
- if (app == null) {
- app = newProcessRecordLocked(info, processName, isolated, isolatedUid);//创建一个新的ProcessRecord。
- if (app == null) {
- return null;
- }
- app.crashHandler = crashHandler;
- mProcessNames.put(processName, app.uid, app);//将ProcessRecord存入mProcessNames。
- if (isolated) {
- mIsolatedProcesses.put(app.uid, app);
- }
- } else {
- // If this is a new package in the process, add the package to the list
- app.addPackage(info.packageName, info.versionCode, mProcessStats);
- checkTime(startTime, "startProcess: added package to existing proc");
- }
- ......
- //调用startProcessLocked()。
- startProcessLocked(
- app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
- checkTime(startTime, "startProcess: done starting proc!");
- return (app.pid != 0) ? app : null;
- }
startProcessLocked方法,首先查询是否有mProcessNames是否有该进程名对应的ProcessRecord信息,如果有直接复用,本例不存在。创建一个新的ProcessRecord,并存入mProcessNames。然后调用重载startProcessLocedd()方法。
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
//app.pid未分配为0
if (app.pid > 0 && app.pid != MY_PID) {
......
}
......
try {
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
int[] permGids = null;
try {
final PackageManager pm = mContext.getPackageManager();
//通过packageManager获取应用程序组id
permGids = pm.getPackageGids(app.info.packageName);
......
} catch (PackageManager.NameNotFoundException e) {
}
/*
* Add shared application and profile GIDs so applications can share some
* resources like shared libraries and access user-wide resources
*/
if (permGids == null) {
gids = new int[2];
} else {
gids = new int[permGids.length + 2];
System.arraycopy(permGids, 0, gids, 2, permGids.length);
}
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
......
int debugFlags = 0;
//debug相关
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
......
}
......
String instructionSet = null;
if (app.info.primaryCpuAbi != null) {
instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
}
app.gids = gids;
app.requiredAbi = requiredAbi;
app.instructionSet = instructionSet;
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
//创建进程,本质是fork出一个子进程,然后在子进程中调用android.app.ActivityThread类的main方法。
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
......
app.setPid(startResult.pid);
app.usingWrapper = startResult.usingWrapper;
app.removed = false;
app.killed = false;
app.killedByAm = false;
synchronized (mPidsSelfLocked) {
//将应用程序信息存入mPidsSelfLocked中,以pid为键
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {//超时处理
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
} catch (RuntimeException e) {
}
}
startProcessLocked方法中,查询当前应用程序的组id,然后调用Process.start方法创建应用程序进程,入口点为android.app.ActivityThread的main方法。创建完毕后,程序有了自己的pid,将对应的processRecord存入mPidsSelfLocked中。最后发送超时处理。下面进入应用程序启动阶段。
/frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
SamplingProfilerIntegration.start();
......
Process.setArgV0("<pre-initialized>");//设置临时进程名
Looper.prepareMainLooper();//准备looper消息循环
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();//loop循环
throw new RuntimeException("Main thread loop unexpectedly exited");
}
main方法中,首先设置临时的进程名,准备消息循环,调用了ActivityThread的attach方法。
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {//system为fasle。
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());//设置DDMS中临时现实的进程名。
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {//获取ActivityManagerService的代理对象,调用attachApplication方法。
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
.......
});
} else {
......
}
......
});
}
attach方法中,设置里DDMS中临时显示的名字,然后调用了ActivityManagerService中的attachApplication方法。跟踪attachApplication方法,又调用到了attachApplicationLocked()方法。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;
//pid为Settings的pid,满足条件
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
if (app == null) {//不满足
......
}
// If this application record is still attached to a previous
// process, clean it up now.
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
final String processName = app.processName;
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);//监控进程的退出
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
}
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);//移除attach之前创建的超时信息。
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
//获取应用的ContentProvider
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
try {
......//调用bindApplication()方法。
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
}
// Remove this record from the list of starting applications.
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
boolean badApp = false;
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {//调用attachApplicationLocked()方法,启动Activity
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
}
}
......
if (!didSomething) {
updateOomAdjLocked();
}
return true;
}
attachApplicationLocked方法中,首先在mPidsSelfLocked中找到对应的ProcessRecord,然后去赋值。移除超时消息,调用bindApplication()方法,调用attachApplicationLocked()方法启动Activity。
/frameworks/base/core/java/android/app/ActivityThread.java
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
......
setCoreSettings(coreSettings);//SettingsProvider数据库监听。
IPackageManager pm = getPackageManager();
android.content.pm.PackageInfo pi = null;
try {
pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
} catch (RemoteException e) {
}
......
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
......
sendMessage(H.BIND_APPLICATION, data);
}
bindApplication()方法中,利用消息循环发送消息BIND_APPLICATION。调用到handleBindApplication()方法。
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
......
// 设置进程名跟DDMS名称。
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
UserHandle.myUserId());
......
//创建对应的context。
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
if (!Process.isIsolated()) {
final File cacheDir = appContext.getCacheDir();
//临时文件
if (cacheDir != null) {
// Provide a usable directory for temporary files
System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
setupGraphicsSupport(data.info, cacheDir);
} else {
}
}
......
/**
* Initialize the default http proxy in this process for the reasons we set the time zone.
*/
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
// In pre-boot mode (doing initial launch to collect password), not
// all system is up. This includes the connectivity service, so don't
// crash if we can't get it.
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try {
final ProxyInfo proxyInfo = service.getDefaultProxy();
Proxy.setHttpProxySystemProperty(proxyInfo);
} catch (RemoteException e) {}
}
if (data.instrumentationName != null) {
......
} else {
mInstrumentation = new Instrumentation();
}
// Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
// probably end up doing the same disk access.
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
try {
//创建Application
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class
if (!data.restrictedBackupMode) {
List<ProviderInfo> providers = data.providers;
if (providers != null) {//查询安装应用providers。
installContentProviders(app, providers);
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);//调用Instrumentation的onCreate方法。
}
catch (Exception e) {
}
try {
mInstrumentation.callApplicationOnCreate(app);//调用Application的onCreate方法。
} catch (Exception e) {
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
handleBindApplication方法中,设置进程名,创建应用的context,创建对应的Application,查询安装ContentProvider,调用Instrumentation的onCreate方法。调用Application的onCreate方法。下面进入attachApplicationLocked方法。
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (realStartActivityLocked(hr, app, true, true)) {//加载Activity。
didSomething = true;
}
} catch (RemoteException e) {
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0);
}
return didSomething;
}
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
......
r.app = app;
app.waitingToKill = null;
r.launchCount++;
r.lastLaunchTime = SystemClock.uptimeMillis();
int idx = app.activities.indexOf(r);
if (idx < 0) {
app.activities.add(r);
}
mService.updateLruProcessLocked(app, true, null);
mService.updateOomAdjLocked();
final ActivityStack stack = r.task.stack;
try {
if (app.thread == null) {
throw new RemoteException();
}
List<ResultInfo> results = null;
List<ReferrerIntent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
}
......
// 加载Activity生命周期
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
r.icicle, r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
if (app.processName.equals(app.info.packageName)) {
if (mService.mHeavyWeightProcess != null
&& mService.mHeavyWeightProcess != app) {
}
mService.mHeavyWeightProcess = app;
Message msg = mService.mHandler.obtainMessage(
ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
msg.obj = r;
mService.mHandler.sendMessage(msg);
}
}
} catch (RemoteException e) {
}
if (andResume) {
stack.minimalResumeActivityLocked(r);//在调用完Activity生命周期后调用此方法,方法内会调用到completeResumeLocked()方法。
} else {
r.state = ActivityState.STOPPED;
r.stopped = true;
}
......
return true;
}
scheduleLaunchActivity调用了ActivityThread.java中的方法,通过消息机制最终调用到了handleLaunchActivity()方法。
/frameworks/base/core/java/android/app/ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
......
//加载onCreate()等方法。
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
//onResume方法。
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
if (!r.activity.mFinished && r.startsNotResumed) {
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
}
r.paused = true;
}
} else {
try {//出错直接finishActivity
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
// Ignore
}
}
}
handleLaunchActivity方法主要是加载Activity的生命周期,onCreate,onStart,onResume等。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//通过反射机制加载创建Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
}
} catch (Exception e) {
}
try {
//创建Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//创建context
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//将各种信息附加到Activity上。
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
......
//调用onCreate()方法。
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();//调用onStart()方法。
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {//回调onRestoreInstanceState()方法。
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {//回调onPostCreate()方法。
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
}
return activity;
}
handleLaunchActivity主要是通过反射加载Activity对象,然后调用生命周期onCreate onStart 等方法。onResume()方法实在handleResumeActivity()这个方法中调用的。
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
// 加载onResume等生命周期方法。
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
final int forwardBit = isForward ?
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
// If the window hasn't yet been added to the window manager,
// and this guy didn't finish itself or start another activity,
// then go ahead and add the window.
boolean willBeVisible = !a.mStartedActivity;
......
// Tell the activity manager we have resumed.
if (reallyResume) {
try {//通知ActivityManagerService resume完毕
ActivityManagerNative.getDefault().activityResumed(token);
} catch (RemoteException ex) {
}
}
} else {
// If an exception was thrown when trying to resume, then
// just end this activity.
try {
ActivityManagerNative.getDefault()
.finishActivity(token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
}
}
}
handleResumeActivity方法主要是调用了performResumedActivity()方法,加载onResume等生命周期方法,最后通知remsum完毕。
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide) {
ActivityClientRecord r = mActivities.get(token);
if (r != null && !r.activity.mFinished) {
if (clearHide) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
try {
r.activity.mFragments.noteStateNotSaved();
if (r.pendingIntents != null) {
deliverNewIntents(r, r.pendingIntents);//调用生命周期onNewIntent方法。
r.pendingIntents = null;
}
if (r.pendingResults != null) {
deliverResults(r, r.pendingResults);//调用生命周期onActivityResult方法。
r.pendingResults = null;
}
r.activity.performResume();//调用生命周期onResume方法。
r.paused = false;
r.stopped = false;
r.state = null;
r.persistentState = null;
} catch (Exception e) {
}
}
return r;
}
final void performResume() {
performRestart();//如果当前Activity处于stop状态,依次调用Activity生命周期的onRestart和onStart方法。
mFragments.execPendingActions();
mLastNonConfigurationInstances = null;
mCalled = false;
// mResumed is set by the instrumentation
mInstrumentation.callActivityOnResume(this);//调用Activity生命周期的onResume方法。
......
mCalled = false;
mFragments.dispatchResume();
mFragments.execPendingActions();
onPostResume();//调用onPostResume方法。
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPostResume()");
}
}
以上调用到了Activity生命周期的onResume方法,调用完成后会回到ActivityStackSupervisor.java中的realStartActivityLocked()方法中,继续执行,调用到stack.minimalResumeActivityLocked(r);
void minimalResumeActivityLocked(ActivityRecord r) {
r.state = ActivityState.RESUMED;
r.stopped = false;
mResumedActivity = r;//将mResumeActivity赋值为要启动的Activity,本例为Settings。
r.task.touchActiveTime();
mService.addRecentTaskLocked(r.task);//加入到Recent列表
completeResumeLocked(r);
mStackSupervisor.checkReadyForSleepLocked();
setLaunchTime(r);
}
minimalResumeActivityLocked首先将状态置为RESUMED状态,将将mResumeActivity赋值为要启动的Activity,加入到Recent列表,然后点用到了completeResumeLocedk()方法。
private void completeResumeLocked(ActivityRecord next) {
......
// schedule an idle timeout in case the app doesn't do it for us.
//onResume方法调用后,会向应用程序主线程加入IDLE状态处理器,ActivityManagerService通过IDLE_TIMEOUT_MSG消息监控。
mStackSupervisor.scheduleIdleTimeoutLocked(next);
mStackSupervisor.reportResumedActivityLocked(next);
next.resumeKeyDispatchingLocked();
mNoAnimActivities.clear();
......
}
}
至此,启动一个Activity的详细过程就分析的差不多了。