这次我们讲下AMS的Activity管理,我们先从如何启动Activity说起。
一、应用startActivity函数
先来看看Activity的startActivity函数:
-
public void startActivity(Intent intent, @Nullable Bundle options) {
-
if (options !=
null) {
-
startActivityForResult(intent, -
1, options);
-
}
else {
-
// Note we want to go through this call for compatibility with
-
// applications that may have overridden the method.
-
startActivityForResult(intent, -
1);
-
}
-
}
再来看下startActivityForResult函数
-
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
-
if (mParent ==
null) {
-
Instrumentation.ActivityResult ar =
-
mInstrumentation.execStartActivity(
-
this, mMainThread.getApplicationThread(), mToken,
this,
-
intent, requestCode, options);
-
......
调用了Instrumentation的execStartActivity函数。
-
public ActivityResult execStartActivity(
-
Context who, IBinder contextThread, IBinder token, Activity target,
-
Intent intent, int requestCode, Bundle options) {
-
IApplicationThread whoThread = (IApplicationThread) contextThread;
-
if (mActivityMonitors !=
null) {
-
synchronized (mSync) {
-
final
int N = mActivityMonitors.size();
-
for (
int i=
0; i<N; i++) {
-
final ActivityMonitor am = mActivityMonitors.get(i);
-
if (am.match(who,
null, intent)) {
-
am.mHits++;
-
if (am.isBlocking()) {
-
return requestCode >=
0 ? am.getResult() :
null;
-
}
-
break;
-
}
-
}
-
}
-
}
-
try {
-
intent.migrateExtraStreamToClipData();
-
intent.prepareToLeaveProcess();
-
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);
-
}
catch (RemoteException e) {
-
}
-
return
null;
-
}
而在Instrumentation的execStartActivity函数中调用了AMS的startActivity函数。至于AMS的startActivity函数我们后续再分析。
有时候我们调用的是context的startActivity函数,最后的是contextImpl的startActivity函数:
-
public void startActivity(Intent intent, Bundle options) {
-
warnIfCallingFromSystemProcess();
-
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) ==
0) {
-
throw
new AndroidRuntimeException(
-
"Calling startActivity() from outside of an Activity "
-
+
" context requires the FLAG_ACTIVITY_NEW_TASK flag."
-
+
" Is this really what you want?");
-
}
-
mMainThread.getInstrumentation().execStartActivity(
-
getOuterContext(), mMainThread.getApplicationThread(),
null,
-
(Activity)
null, intent, -
1, options);
-
}
在contextImpl中的startActivity函数最后也是调用了Instrumentation的execStartActivity函数。
而最终都是通过binder调用AMS的startActivity函数。下面我们看下AMS的startActivity函数:
二、AMS的startActivity函数
下面我们看看AMS的startActivity函数
-
public int startActivity(IBinder whoThread, String callingPackage,
-
Intent intent, String resolvedType, Bundle options) {
-
checkCaller();
-
-
int callingUser = UserHandle.getCallingUserId();
-
TaskRecord tr;
-
IApplicationThread appThread;
-
synchronized (ActivityManagerService.
this) {
-
tr = recentTaskForIdLocked(mTaskId);
-
if (tr ==
null) {
-
throw
new IllegalArgumentException(
"Unable to find task ID " + mTaskId);
-
}
-
appThread = ApplicationThreadNative.asInterface(whoThread);
-
if (appThread ==
null) {
-
throw
new IllegalArgumentException(
"Bad app thread " + appThread);
-
}
-
}
-
return mStackSupervisor.startActivityMayWait(appThread, -
1, callingPackage, intent,
-
resolvedType,
null,
null,
null,
null,
0,
0,
null,
null,
-
null, options, callingUser,
null, tr);
-
}
startActivity方法中调用了ActivityStackSupervisor的startActivityMayWait函数,而在startActivityMayWait又调用了startActivityLocked函数,节选了重要代码:
-
ActivityRecord r =
new ActivityRecord(mService, callerApp, callingUid, callingPackage,
//新建ActivityRecord
-
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
-
requestCode, componentSpecified,
this, container, options);
-
if (outActivity !=
null) {
-
outActivity[
0] = r;
-
}
-
-
final ActivityStack stack = getFocusedStack();
-
if (voiceSession ==
null && (stack.mResumedActivity ==
null
-
|| stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
-
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
//现在不能切换进程,比如在通电话
-
realCallingPid, realCallingUid,
"Activity start")) {
-
PendingActivityLaunch pal =
-
new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
-
mPendingActivityLaunches.add(pal);
//不Activity信息放在mPendingActivityLaunches
-
ActivityOptions.abort(options);
-
return ActivityManager.START_SWITCHES_CANCELED;
-
}
-
}
-
-
if (mService.mDidAppSwitch) {
-
// This is the second allowed switch since we stopped switches,
-
// so now just generally allow switches. Use case: user presses
-
// home (switches disabled, switch to home, mDidAppSwitch now true);
-
// user taps a home icon (coming from home so allowed, we hit here
-
// and now allow anyone to switch again).
-
mService.mAppSwitchesAllowedTime =
0;
-
}
else {
-
mService.mDidAppSwitch =
true;
-
}
-
-
doPendingActivityLaunchesLocked(
false);
//启动挂起等待的Activity
-
-
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
-
startFlags,
true, options, inTask);
//继续启动当前Activity
startActivityUncheckedLocked函数比较长,主要是通过Intent的标志和Activity的属性来确定Activity的Task。
找到Activity的Task后,调用ActivityStack的startActivityLocked方法继续启动。
-
final void startActivityLocked(ActivityRecord r, boolean newTask,
-
boolean doResume,
boolean keepCurTransition, Bundle options) {
-
TaskRecord rTask = r.task;
-
final
int taskId = rTask.taskId;
-
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);
//如果是新的Task,把它放在顶部
-
}
-
TaskRecord task =
null;
-
if (!newTask) {
-
// 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) {
-
if (!startIt) {
-
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;
-
}
-
}
-
}
-
-
if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() -
1)) {
-
mStackSupervisor.mUserLeaving =
false;
-
}
-
-
task = r.task;
-
-
if (DEBUG_ADD_REMOVE) Slog.i(TAG,
"Adding activity " + r +
" to stack to task " + task,
-
new RuntimeException(
"here").fillInStackTrace());
-
task.addActivityToTop(r);
//把Activity放在Task的顶部
-
task.setFrontOfTask();
-
-
r.putInHistory();
-
if (!isHomeStack() || numActivities() >
0) {
-
............
//如果不是Home应用的Stack,WMS准备绘制Activity以及动画
-
}
else {
-
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);
//启动Activity
-
}
-
}
看下上面的注释,最后是调用了ActivityStackSupervisor的resumeTopActivitiesLocked函数,这个函数主要是将位于栈顶的Activity显示出来。最后会调用resumeTopActivityInnerLocked函数:
-
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
-
.............
-
if (next ==
null) {
//如果当前没有Activity,显示Home Activity
-
// There are no more activities! Let's just start up the
-
// Launcher...
-
ActivityOptions.abort(options);
-
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
-
final
int returnTaskType = prevTask ==
null || !prevTask.isOverHomeStack() ?
-
HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
-
return isOnHomeDisplay() &&
-
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev,
"noMoreActivities");
-
}
-
-
next.delayedResume =
false;
-
-
if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
-
mStackSupervisor.allResumedActivitiesComplete()) {
-
//如果当前Activity就是要启动的Activity,直接返回
-
return
false;
-
}
-
-
..............
-
-
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) !=
0;
-
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving,
true, dontWaitForPause);
-
if (mResumedActivity !=
null) {
-
//暂停当前Activity
-
pausing |= startPausingLocked(userLeaving,
false,
true, dontWaitForPause);
-
}
-
if (pausing) {
-
.........
//如果系统正在暂停Activity,先退出
-
return
true;
-
}
-
-
-
boolean anim =
true;
-
......
//调用WMS的方法处理Activity的显示
-
-
ActivityStack lastStack = mStackSupervisor.getLastStack();
-
if (next.app !=
null && next.app.thread !=
null) {
-
//如果Activity所在的应用已经存在,把Activity显示出来
-
-
// This activity is now becoming visible.
-
mWindowManager.setAppVisibility(next.appToken,
true);
-
-
...........
-
-
try {
-
// Deliver all pending results.
-
ArrayList<ResultInfo> a = next.results;
-
if (a !=
null) {
-
final
int N = a.size();
-
if (!next.finishing && N >
0) {
-
if (DEBUG_RESULTS) Slog.v(
-
TAG,
"Delivering results to " + next
-
+
": " + a);
-
next.app.thread.scheduleSendResult(next.appToken, a);
-
}
-
}
-
-
if (next.newIntents !=
null) {
-
next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
-
}
-
-
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
-
System.identityHashCode(next), next.task.taskId, next.shortComponentName);
-
-
next.sleeping =
false;
-
mService.showAskCompatModeDialogLocked(next);
-
next.app.pendingUiClean =
true;
-
next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
-
next.clearOptionsLocked();
-
//调用onResume方法
-
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
-
mService.isNextTransitionForward(), resumeAnimOptions);
-
-
mStackSupervisor.checkReadyForSleepLocked();
-
-
if (DEBUG_STATES) Slog.d(TAG,
"resumeTopActivityLocked: Resumed " + next);
-
}
catch (Exception e) {
-
.........
-
return
true;
-
}
-
else {
-
.........
//Activity应用进程没有,先启动进程
-
mStackSupervisor.startSpecificActivityLocked(next,
true,
true);
-
}
-
return
true;
-
}
resumeTopActivitiesLocked,如果Activity的应用已经启动,就调用应用进程的scheduleResumeActivity方法,最终到应用的onResume方法,如果应用还没启动调用startSpecificActivityLocked方法。
-
void startSpecificActivityLocked(ActivityRecord r,
-
boolean andResume,
boolean checkConfig) {
-
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)) {
-
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
-
mService.mProcessStats);
-
}
-
realStartActivityLocked(r, app, andResume, checkConfig);
-
return;
-
}
catch (RemoteException e) {.....
-
}
-
-
}
-
-
mService.startProcessLocked(r.processName, r.info.applicationInfo,
true,
0,
-
"activity", r.intent.getComponent(),
false,
false,
true);
-
}
startSpecificActivityLocked方法中,如果发现没有启动应用,就调用mService.startProcessLocked。在startProcessLocked会新建一个ProcessRecord保存下来,最终会调用Process.start方法启动新进程。
而如果进程已经启动会调用realStartActivityLocked方法,这个方法中会调用app.thread.scheduleLaunchActivity函数,最终调用应用的onCreate方法。
三、ActivityThread的启动
启动应用的进程的话,会调用ActivityThread的main方法:
-
public static void main(String[] args) {
-
SamplingProfilerIntegration.start();
-
-
CloseGuard.setEnabled(
false);
-
-
Environment.initForCurrentUser();
-
-
EventLogger.setReporter(
new EventLoggingReporter());
-
-
Security.addProvider(
new AndroidKeyStoreProvider());
-
-
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
-
TrustedCertificateStore.setDefaultUserDirectory(configDir);
-
-
Process.setArgV0(
"<pre-initialized>");
-
-
Looper.prepareMainLooper();
-
-
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();
//进去消息循环
-
-
throw
new RuntimeException(
"Main thread loop unexpectedly exited");
-
}
上面调用了ActivityThread的attach方法:
-
private void attach(boolean system) {
-
sCurrentActivityThread =
this;
-
mSystemThread = system;
-
if (!system) {
//非系统应用
-
ViewRootImpl.addFirstDrawHandler(
new Runnable() {
-
@Override
-
public void run() {
-
ensureJitEnabled();
-
}
-
});
-
android.ddm.DdmHandleAppName.setAppName(
"<pre-initialized>",
-
UserHandle.myUserId());
-
RuntimeInit.setApplicationObject(mAppThread.asBinder());
-
final IActivityManager mgr = ActivityManagerNative.getDefault();
-
try {
-
mgr.attachApplication(mAppThread);
//调用AMS的attachApplication
-
......
在ActivityThread中,把ApplicationThread这个Binder服务端传给AMS。
-
private final boolean attachApplicationLocked(IApplicationThread thread,
-
int pid) {
-
-
............
-
ProfilerInfo profilerInfo = profileFile ==
null ?
null
-
:
new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
-
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
//调用应用的bindApplication接口
-
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) {
-
..........
-
return
false;
-
}
-
-
......
-
boolean badApp =
false;
-
boolean didSomething =
false;
-
-
if (normalMode) {
-
try {
//处理挂起的Activity
-
if (mStackSupervisor.attachApplicationLocked(app)) {
-
didSomething =
true;
-
}
-
}
catch (Exception e) { badApp =
true;}
-
}
-
-
// Find any services that should be running in this process...
-
if (!badApp) {
-
try {
//处理挂起的Service
-
didSomething |= mServices.attachApplicationLocked(app, processName);
-
}
catch (Exception e) {badApp =
true;}
-
}
-
-
-
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
-
try {
//发起挂起的广播
-
didSomething |= sendPendingBroadcastsLocked(app);
-
}
catch (Exception e) {badApp =
true;}
-
}
-
-
...........
-
-
return
true;
-
}
attachApplicationLocked方法,先调用了ApplicationThread的接口bindApplication,这样就到应用ActivityThread中了,在ActivityThread在handleBindApplication中主要是初始化应用的数据。
调用完这个方法后,还会调用mStackSupervisor.attachApplicationLocked,这个方法主要调用了realStartActivityLocked,这个方法前面分析过了。这边进程已经启动,就调用
app.thread.scheduleLaunchActivity,在这个方法中创建了ActivityClientRecord。然后发送了一个消息。
-
@
Override
-
public final
void
scheduleLaunchActivity
(Intent intent, IBinder token, int ident,
-
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
-
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
-
int procState, Bundle state, PersistableBundle persistentState,
-
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
-
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
-
-
updateProcessState(procState,
false);
-
-
ActivityClientRecord r =
new ActivityClientRecord();
-
-
r.token = token;
-
r.ident = ident;
-
r.intent = intent;
-
r.referrer = referrer;
-
r.voiceInteractor = voiceInteractor;
-
r.activityInfo = info;
-
r.compatInfo = compatInfo;
-
r.state = state;
-
r.persistentState = persistentState;
-
-
r.pendingResults = pendingResults;
-
r.pendingIntents = pendingNewIntents;
-
-
r.startsNotResumed = notResumed;
-
r.isForward = isForward;
-
-
r.profilerInfo = profilerInfo;
-
-
r.overrideConfig = overrideConfig;
-
updatePendingConfiguration(curConfig);
-
-
sendMessage(H.LAUNCH_ACTIVITY, r);
-
}
消息处理会执行到handleLaunchActivity函数,在performLaunchActivity函数中会创建Activity,并且调用Activity的attach方法创建PhoneWindow等,在performActivity方法中会把这个ActivityClientRecord对象放到mActivities中去。我们来看下代码:
-
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
-
......
-
Activity activity = null;
-
try {
-
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
-
activity = mInstrumentation.newActivity(
//创建Activity
-
cl, component.getClassName(), r.intent);
-
StrictMode.incrementExpectedActivityCount(activity.getClass());
-
r.intent.setExtrasClassLoader(cl);
-
r.intent.prepareToEnterProcess();
-
if (r.state != null) {
-
r.state.setClassLoader(cl);
-
}
-
}
catch (Exception e) {
-
if (!mInstrumentation.onException(activity, e)) {
-
throw
new RuntimeException(
-
"Unable to instantiate activity " + component
-
+
": " + e.toString(), e);
-
}
-
}
-
-
try {
-
Application app = r.packageInfo.makeApplication(
false, mInstrumentation);
-
-
if (activity != null) {
-
Context appContext = createBaseContextForActivity(r, activity);
-
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
-
Configuration config =
new Configuration(mCompatConfiguration);
-
if (DEBUG_CONFIGURATION) Slog.v(TAG,
"Launching activity "
-
+ r.activityInfo.name +
" with config " + config);
-
activity.attach(appContext,
this, getInstrumentation(), r.token,
//Activity的attach方法
-
r.ident, app, r.intent, r.activityInfo, title, r.parent,
-
r.embeddedID, r.lastNonConfigurationInstances, config,
-
r.referrer, r.voiceInteractor);
-
-
if (customIntent != null) {
-
activity.mIntent = customIntent;
-
}
-
r.lastNonConfigurationInstances = null;
-
activity.mStartedActivity =
false;
-
int theme = r.activityInfo.getThemeResource();
-
if (theme !=
0) {
-
activity.setTheme(theme);
-
}
-
-
activity.mCalled =
false;
-
if (r.isPersistable()) {
-
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
-
}
else {
-
mInstrumentation.callActivityOnCreate(activity, r.state);
//调用Activity的onCreate函数
-
}
-
......
-
-
mActivities.put(r.token, r);
//将ActivityClientRecord放入mActivities中
-
......