在上篇博客中说到有两种方式启动进程,其中一种就是点击Launcher界面,在点击Launcher最后也会调用Activity的startActivity方法,但是在Launcher中会调用如下代码:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
这句代码代表启动这个Activity的时候要新建一个Task,主要在AMS中所有的Activity都是保存在Task中。
我们再来看一般的Activity的主Activity其AndroidManifest.xml文件
因此,这里的intent包含的信息为:action = "android.intent.action.Main",category="android.intent.category.LAUNCHER"。
然后我们继续分析,Activity的startActivity函数,最终会到AMS的startActivity函数,这中间的过程就不分析了,在之前的博客中分析过。我们来看AMS的startActivity函数,最终是在ActivityStackSupervisor的startActivityMayWait函数中。
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
我们来看下ActivityStackSupervisor的startActivityMayWait函数,先是主要调用了resolveActivity函数来解析intent的数据,也就是之前AndroidManifest.xml里的内容。
ActivityInfo aInfo =
resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
我们来看下resolveActivity函数主要还是通过PKMS来解析Intent,并且也设置了Intent的Component。
ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
ProfilerInfo profilerInfo, int userId) {
// Collect information about the target of the Intent.
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| ActivityManagerService.STOCK_PM_FLAGS, userId);
aInfo = rInfo != null ? rInfo.activityInfo : null;
} catch (RemoteException e) {
aInfo = null;
}
if (aInfo != null) {
// Store the found target back into the intent, because now that
// we have it we never want to do this again. For example, if the
// user navigates back to this point in the history, we should
// always restart the exact same activity.
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't debug things in the system process
if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
if (!aInfo.processName.equals("system")) {
mService.setDebugApp(aInfo.processName, true, false);
}
}
if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
if (!aInfo.processName.equals("system")) {
mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
}
}
if (profilerInfo != null) {
if (!aInfo.processName.equals("system")) {
mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
}
}
}
return aInfo;
}
后面又调用了ActivityStackSupervisor的startActivityLocked函数,在这个函数中主要创建了ActivityRecord对象
下面我们继续startActivityUncheckedLocked方法,我们先看下面这段代码,由于这个intent的标志值的位Intent.FLAG_ACTIVITY_NEW_TASK被置位,而且Intent.FLAG_ACTIVITY_MULTIPLE_TASK没有置位,因此,下面的if语句会被执行。
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.
ActivityRecord intentActivity = !launchSingleInstance ?
findTaskLocked(r) : findActivityLocked(intent, r.info);
if (intentActivity != null) {
这段代码的逻辑是查看一下,当前有没有Task可以用来执行这个Activity。由于r.launchMode的值不为ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过findTaskLocked函数来查找存不存这样的Task,这里返回的结果是null,即taskTop为null,因此,需要创建一个新的Task来启动这个Activity。
接着往下看:
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 = mFocusedStack;
ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
if (top != null && r.resultTo == null) {
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;
}
}
}
}
这段代码的逻辑是看一下,当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,因此,这里不用进一步处理上述介绍的情况。
执行到这里,我们知道,要在一个新的Task里面来启动这个Activity了,于是新创建一个Task,并且将这个Task设置为ActivityRecord的task成员变量
if (r.resultTo == null && inTask == null && !addingToTask
&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;//新建一个task
targetStack = computeStackFocus(r, newTask);
targetStack.moveToFront("startingNewTask");
if (reuseTask == null) {
r.setTask(targetStack.createTaskRecord(getNextTaskId(),
newTaskInfo != null ? newTaskInfo : r.info,
newTaskIntent != null ? newTaskIntent : intent,
voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
taskToAffiliate);
if (DEBUG_TASKS) Slog.v(TAG_TASKS,
"Starting new activity " + r + " in new task " + r.task);
}
调用了ActivityStatck来创建一个Task,并且在这个函数中调用了addTask函数
TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
boolean toTop) {
TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
voiceInteractor);
addTask(task, toTop, false);
return task;
}
addTask函数也将这个task放入mTaskHistory一个合适的位置。
void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
task.stack = this;
if (toTop) {
insertTaskAtTop(task, null);
} else {
mTaskHistory.add(0, task);
updateTaskMovement(task, false);
}
if (!moving && task.voiceSession != null) {
try {
task.voiceSession.taskStarted(task.intent, task.taskId);
} catch (RemoteException e) {
}
}
}
下面继续调用了ActivityStack的startActivityLocked函数,在这个函数最后有如下代码,当然这个doResume为true。
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
然后又回到ActivityStackSupervisor类,调用了其resumeTopActivitiesLocked方法。最后会调用resumeTopActivityInnerLocked函数,我们直接看这个函数:
final ActivityRecord next = topRunningActivityLocked(null);
先获取了下个ActivityRecord,这里也就是我们要启动的Activity。
然后会调用startPausingLocked,把当前的Activity pause。注意这里调用了startPausingLocked之前就return了。
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
"resumeTopActivityLocked: Skip resume: need to start 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;
}
我们再来看startPausingLocked函数,在startPausingLocked函数中调用了ActivityThread的schedulePauseActivity函数:
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
......
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
......
在ActivityThread中最后调用handlePauseActivity函数来处理,在handlePauseActivity函数中调用performPauseActivity函数最后会调用Activity的onPause方法,在这个函数最后调用了AMS的activityPaused方法。
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
Slog.d(TAG, "userLeaving=" + userLeaving + " handling pause of " + r + ",isPreHoney" + r.isPreHoneycomb() +
"dontReport :"+ dontReport);
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb());
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName() + ",performPauseActivity ok done.");
Slog.d(TAG, "performPauseActivity after");
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
Slog.e(TAG,"handlePauseActivity RemoteException: " + ex);
}
}
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName() + ",ActivityManager activityPaused ok done.");
mSomeActivitiesChanged = true;
}
}
最后通过AMS的activityPausedLocked方法,又调用了ActivityStack的activityPausedLocked方法,然后调用了completePauseLocked方法,最后又到了ActivityStackSupervisor的resumeTopActivitiesLocked方法,于是又回到了resumeTopActivityInnerLocked方法,在这个函数最后又如下代码:这个时候我们要启动的Activity的进程还没启动,所以其app和app.thread为null。
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
......
} else {
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, "ActivityStack resumeTopActivityInnerLock startSpecificActivityLocked fork process");
// 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);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
所以最后到了ActivityStackSupervisor的startSpecificActivityLocked函数,这个函数如果当前Activity的进程没有,会调用AMS的startProcessLocked函数
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
最后会在startProcessLocked中创建进程,然后直接到ActivityThread的main函数。这里的过程就不分析,然后在ActivityThread的main函数调用了AMS的attachApplication函数。在attachApplicationLocked中创建了一个ProcessRecord对象,调用了ActivityThread的bindApplication来完成进程的一些初始化工作。然后又调用了ActivityStackSupervisor的attachApplicationLocked函数,在这个函数又调用了realStartActivityLocked函数,然后在这个函数调用了app.thread.scheduleLaunchActivity函数,就到ActivityThread的scheduleLaunchActivity函数了,下面我们在之前博客分析过了就不分析了。