final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
r.startFreezingScreenLocked(app, );//冻结屏幕
if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
mWindowManager.setAppVisibility(r.appToken, true);//设置app的r可见
// schedule launch ticks to collect information about slow apps.
r.startLaunchTickingLocked();//打印启动日志
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order. Note that
// as a result of this, it can call back into the activity
// manager with a new orientation. We don't care about that,
// because the activity is not currently running so we are
// just restarting it anyway.
if (checkConfig) {
Configuration config = mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
//处理Config发生变化的情况
mService.updateConfigurationLocked(config, r, false, false);
}
r.app = app;
app.waitingToKill = null;
r.launchCount++;
r.lastLaunchTime = SystemClock.uptimeMillis();
/// M: AMS log enhancement @{
if (localLOGV) Slog.v(TAG, "ACT-Launching: " + r);
/// @}
int idx = app.activities.indexOf(r);
//将ActivityRecord加到ProcessRecord的activities中保存
if (idx < ) {
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<Intent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
}
if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
+ " icicle=" + r.icicle
+ " with results=" + results + " newIntents=" + newIntents
+ " andResume=" + andResume);
if (andResume) {
EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
r.userId, System.identityHashCode(r),
r.task.taskId, r.shortComponentName);
/// M: AMS log enhancement @{
if (!ActivityManagerService.IS_USER_BUILD)
Slog.d(TAG, "ACT-AM_RESTART_ACTIVITY " + r + " Task:" + r.task.taskId);
/// @}
}
if (r.isHomeActivity() && r.isNotResolverActivity()) {//是home程序且不是ResolverActivity
// Home process is the root process of the task.
mService.mHomeProcess = r.task.mActivities.get().app;
}
mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
对该APK做dex优化
r.sleeping = false;
r.forceNewConfig = false;
mService.showAskCompatModeDialogLocked(r);
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
String profileFile = null;
ParcelFileDescriptor profileFd = null;
boolean profileAutoStop = false;
if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
if (mService.mProfileProc == null || mService.mProfileProc == app) {
mService.mProfileProc = app;
profileFile = mService.mProfileFile;
profileFd = mService.mProfileFd;
profileAutoStop = mService.mAutoStopProfiler;
}
}
app.hasShownUi = true;
app.pendingUiClean = true;
if (profileFd != null) {
try {
profileFd = profileFd.dup();
} catch (IOException e) {
if (profileFd != null) {
try {
profileFd.close();
} catch (IOException o) {
}
profileFd = null;
}
}
}
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);//设置进程为当前Activity所属进程所有者
mService.logAppLaunchTime(TAG, "scheduleLaunchActivity -> ActivityThread"); /// M: It's for debugging App Launch time
//通知应用进程启动Activity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration), r.compat,
app.repProcState, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != ) {
// This may be a heavy-weight process! Note that the package
// manager will ensure that only activity can run in the main
// process of the .apk, which is the only thing that will be
// considered heavy-weight.
if (app.processName.equals(app.info.packageName)) {
if (mService.mHeavyWeightProcess != null
&& mService.mHeavyWeightProcess != app) {
Slog.w(TAG, "Starting new heavy weight process " + app
+ " when already running "
+ mService.mHeavyWeightProcess);
}
mService.mHeavyWeightProcess = app;
Message msg = mService.mHandler.obtainMessage(
ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
msg.obj = r;
mService.mHandler.sendMessage(msg);
}
}
} catch (RemoteException e) {
if (r.launchFailed) {
// This is the second time we failed -- finish activity
// and give up.
Slog.e(TAG, "Second failure launching "
+ r.intent.getComponent().flattenToShortString()
+ ", giving up", e);
mService.appDiedLocked(app, app.pid, app.thread);
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
}
/// M: fix google issue, add to prevent process starting repeatly
/// If AP is in 2nd crash, we will stop trying to start AP process. @{
r.launchFailed = true;
/// @}
// This is the first time we failed -- restart process and
// retry.
app.activities.remove(r);
throw e;
}
r.launchFailed = false;
if (stack.updateLRUListLocked(r)) {//更新oodm 进程优先级
Slog.w(TAG, "Activity " + r
+ " being launched, but already in LRU list");
}
if (andResume) {
// As part of the process of launching, ActivityThread also performs
// a resume.
stack.minimalResumeActivityLocked(r);//完成 Activity 启动
} else {
// This activity is not starting in the resumed state... which
// should look like we asked it to pause+stop (but remain visible),
// and it has done so and reported back the current icicle and
// other state.
if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
+ " (starting in stopped state)");
r.state = ActivityState.STOPPED;
r.stopped = true;
}
// Launch the new version setup screen if needed. We do this -after-
// launching the initial activity (that is, home), so that it can have
// a chance to initialize itself while in the background, making the
// switch back to it faster and look better.
if (isFrontStack(stack)) {
mService.startSetupActivityLocked();//是否更新 ui显示
}
return true;
}
调用 ProcessRecord.thread ( ActivityThread 类型)的 scheduleLaunchActivity() 通知应用的主进程启动 Activity :
AMS通过realStartActivityLocked函数来调度应用程序进程启动一个Activity,参数r为即将启动的Activity在AMS服务中的描述符,参数app为Activity运行所在的应用程序进程在AMS服务中的描述符。函数通过IApplicationThread代理对象ApplicationThreadProxy通知应用程序进程启动r对应的Activity,应用程序进程完成Activity的加载等准备工作后,AMS最后启动该Activity。启动Activity的创建等工作是在应用程序进程中完成的,AMS是通过IApplicationThread接口和应用程序进程通信的。r.appToken 在AMS服务端的类型为Token,是IApplicationToken的Binder本地对象。
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
int procState, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
参数token从AMS服务端经过Binder传输到应用程序进程后,变为IApplicationToken的Binder代理对象,类型为IApplicationToken.Proxy,这是因为AMS和应用程序运行在不同的进程中。
通过queueOrSendMessage函数将Binder跨进程调用转换为应用程序进程中的异步消息处理
上述代码最后调用到
public void handleMessage(Message msg) {
......
switch (msg.what) {
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
//ActivityClientRecord 代表着在应用进程中的一个Activity
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
}
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo) ->
getPackageInfo(ai, compatInfo, null, false, true) ->
new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0)
获得当前 Activity的LoadedApk对象。
public LoadedApk(ActivityThread activityThread, String name,
Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {
mActivityThread = activityThread;
mApplicationInfo = info != null ? info : new ApplicationInfo();
mApplicationInfo.packageName = name;
mPackageName = name;
mAppDir = null;
mResDir = null;
mSharedLibraries = null;
mDataDir = null;
mDataDirFile = null;
mLibDir = null;
mBaseClassLoader = null;
mSecurityViolation = false;
mIncludeCode = true;
mClassLoader = systemContext.getClassLoader();
mResources = systemContext.getResources();
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
}
LoadedApk类记录了Activity运行所在的ActivityThread、Activity所在的应用程序信息、Activity的包名、Activity的资源路径、Activity的库路径、Activity的数据存储路径、类加载器和应用程序所使用的资源等信息
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) { //如果 LoadedApk 为null,重新获取LoadedApk
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();//获取Activity的 ComponentName
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
//packageName为启动Activity的包名,targetActivity为Activity的类名
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
//通过类反射方式加载即将启动的Activity
//利用Class loader和ComponentName对象搭配
//mInstrumentation.newActivity函数产生一个新的activity对象.
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
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对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV || mIsUserBuild) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
//为当前Activity创建上下文对象ContextImpl
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和上下文ContextImpl、Application绑定
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
}
//设定activity的参数intent设定跟背景主题设定
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != ) {
activity.setTheme(theme);
}
activity.mCalled = false;
//调用Activity的OnCreate函数
mInstrumentation.callActivityOnCreate(activity, r.state);
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
//将Activity保存到ActivityClientRecord中,ActivityClientRecord为Activity在应用程序进程中的描述符
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {//mFinished 表示
if (r.state != null) {
//在activity被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle)
//(传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个activity被杀死前调用
//,当该activity在将来某个时刻回来时可以恢复其先前状态。
//最终会调用onRestoreInstanceState 方法 ,将 activity恢复其先前状态
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
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;
//ActivityThread的成员变量mActivities保存了当前应用程序进程中的所有Activity的描述符
mActivities.put(r.token, r);
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
在该函数中,首先通过PMS服务查找到即将启动的Activity的包名信息,然后通过类反射方式创建一个该Activity实例,同时为应用程序启动的每一个Activity创建一个LoadedApk实例对象,应用程序进程中创建的所有LoadedApk对象保存在ActivityThread的成员变量mPackages中。接着通过LoadedApk对象的makeApplication函数,使用单例模式创建Application对象,因此在android应用程序进程中有且只有一个Application实例。然后为当前启动的Activity创建一个ContextImpl上下文对象,并初始化该上下文,到此我们可以知道,启动一个Activity需要以下对象:
1) XXActivity对象,需要启动的Activity;
2) LoadedApk对象,每个启动的Activity都拥有属于自身的LoadedApk对象;
3) ContextImpl对象,每个启动的Activity都拥有属于自身的ContextImpl对象;
4) Application对象,应用程序进程中有且只有一个实例,和Activity是一对多的关系;
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide) {
ActivityClientRecord r = mActivities.get(token);//找出当前要启动的Activities
if (localLOGV || mIsUserBuild) Slog.v(TAG, "Performing resume of " + r
+ " finished=" + ((r != null && r.activity != null)
? r.activity.mFinished : null));
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);//当在singleTask 或者singleTop模式下,系统中只会存在一个
//Activity实例,所以当我们要启动这个实例的时候,如果发现系统中已经存在activity,就会执行onNewIntent
r.pendingIntents = null;
}
if (r.pendingResults != null) {
deliverResults(r, r.pendingResults);
r.pendingResults = null;
}
r.activity.performResume();
//会先执行 performRestart -> activity.onRestart()
// 接着 -> callActivityOnResume-> activity.onResume
EventLog.writeEvent(LOG_ON_RESUME_CALLED,
UserHandle.myUserId(), r.activity.getComponentName().getClassName());
/// M: ActivityThread log enhancement @{
if(!mIsUserBuild)
Slog.d(TAG, "ACT-AM_ON_RESUME_CALLED " + r);
/// @}
r.paused = false;
r.stopped = false;
r.state = null;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to resume activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
return r;
}
调用activity.performResume()方法,在activity.performResume()中会默认先调用performRestart(),performRestart()的作用是先检查activity是否处于stopped状态,如果是则调用performRestart()再调用performStart()。最后再响应activity的生命周期方法onResume()。
所以,新打开一个activity的响应流程是:
onCreate()->onStart()->onResume()
而返回一个后台activity的响应流程是:
onRestart()->onStart()->onResume()
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
boolean reallyResume) {
if (r.window == null && !a.mFinished && willBeVisible) {
//获得为当前Activity创建的窗口PhoneWindow对象
r.window = r.activity.getWindow();
//获取为窗口创建的视图DecorView对象
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
//在attach函数中就为当前Activity创建了WindowManager对象
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
//得到该视图对象的布局参数
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
//将创建的视图对象DecorView添加到Activity的窗口管理器中
wm.addView(decor, l);
}
......
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
//将当前Activity的视图显示出来
}
...
Looper.myQueue().addIdleHandler(new Idler());
//一是调用方法finishUserBoot()把状态还是STATE_BOOTING的用户切换到STATE_RUNNING状态
//,同时发送广播ACTION_BOOT_COMPLETED给该用户,表示用户启动结束。另一件工作是停止多余的用户
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
Configuration config) {
if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
/// M: PerfBoost @{
if (mIsPerfBoostEnable) {
PerfService.nativePerfBoostDisable(PerfService.SCN_APP_SWITCH);
mIsPerfBoostEnable = false;
}
/// @}
ArrayList<ActivityRecord> stops = null;
ArrayList<ActivityRecord> finishes = null;
ArrayList<UserStartedState> startingUsers = null;
int NS = ;
int NF = ;
IApplicationThread sendThumbnail = null;
boolean booting = false;
boolean enableScreen = false;
boolean activityRemoved = false;
ActivityRecord r = ActivityRecord.forToken(token);//找到当前的 ActivityRecord
if (r != null) {
if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
Debug.getCallers());
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);//移除IDLE_TIMEOUT_MSG 消息
r.finishLaunchTickingLocked();
if (fromTimeout) {
reportActivityLaunchedLocked(fromTimeout, r, -, -);
}
// This is a hack to semi-deal with a race condition
// in the client where it can be constructed with a
// newer configuration from when we asked it to launch.
// We'll update with whatever configuration it now says
// it used to launch.
if (config != null) {
r.configuration = config;
}
// We are now idle. If someone is waiting for a thumbnail from
// us, we can now deliver.
r.idle = true;//当前我们已经进入idle模式。并且已经移除IDLE_TIMEOUT_MSG,所以为 true
if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
sendThumbnail = r.app.thread;
r.thumbnailNeeded = false;
}
//Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
if (!mService.mBooted && isFrontStack(r.task.stack)) {
mService.mBooted = true;
enableScreen = true;
}
}
if (allResumedActivitiesIdle()) {//所以此处 内部我们判断r.idle为true
if (r != null) {
mService.scheduleAppGcsLocked();//知所有进行中的任务进行垃圾回收
}
/*
mLaunchingActivity是一个WakeLock,它能防止在操作Activity过程中掉电,同时
这个WakeLock又不能长时间使用,否则有可能耗费过多电量。所以,系统设置了一个超时
处理消息LAUNCH_TIMEOUT_MSG,超时时间为10秒。一旦目标Activity启动成功,
就需要需要释放 WakeLock
*/
if (mLaunchingActivity.isHeld()) {
mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
if (VALIDATE_WAKE_LOCK_CALLER &&
Binder.getCallingUid() != Process.myUid()) {
throw new IllegalStateException("Calling must be system uid");
}
mLaunchingActivity.release();
}
ensureActivitiesVisibleLocked(null, );
}
// Atomically retrieve all of the other things to do.
stops = processStoppingActivitiesLocked(true);// 得到因本次启动而被 pause 的 Activity
NS = stops != null ? stops.size() : ;
if ((NF=mFinishingActivities.size()) > ) {
finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
mFinishingActivities.clear();
}
final ArrayList<ActivityRecord> thumbnails;
final int NT = mCancelledThumbnails.size();
if (NT > ) {
thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
mCancelledThumbnails.clear();
} else {
thumbnails = null;
}
if (isFrontStack(mHomeStack)) {
booting = mService.mBooting;
mService.mBooting = false;
}
if (mStartingUsers.size() > ) {
startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
mStartingUsers.clear();
}
// Perform the following actions from unsynchronized state.
final IApplicationThread thumbnailThread = sendThumbnail;
mHandler.post(new Runnable() {
@Override
public void run() {
if (thumbnailThread != null) {
try {
thumbnailThread.requestThumbnail(token);
} catch (Exception e) {
Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
mService.sendPendingThumbnail(null, token, null, null, true);
}
}
// Report back to any thumbnail receivers.
for (int i = ; i < NT; i++) {
ActivityRecord r = thumbnails.get(i);
mService.sendPendingThumbnail(r, null, null, null, true);
}
}
});
// Stop any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = ; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.task.stack;
if (r.finishing) {
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
// 如果被暂停的Activity处于finishing状态(例如Activity在其onStop中调用了finish函数),则调用finishCurrentActivityLocked
} else {
stack.stopActivityLocked(r);
}
}
// Finish any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = ; i < NF; i++) {
r = finishes.get(i);
activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
}
if (booting) {//如果是系统开机启动桌面。此时启动完成发广播 ACTION_BOOT_COMPLETED
mService.finishBooting();
} else if (startingUsers != null) {
for (int i = ; i < startingUsers.size(); i++) {
mService.finishUserSwitch(startingUsers.get(i));
}
}
mService.trimApplications();
//dump();
//mWindowManager.dump();
if (enableScreen) {
mService.enableScreenAfterBoot();
}
if (activityRemoved) {
resumeTopActivitiesLocked();
}
return r;
}
在startPausingLocked()时会将要paused的ActivityRecord保存在mPausingActivity中,当pause成功后会调用activityPausedLocked()函数做后续处理,在这个函数中会将mPausingActivity重置为null
final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
if (mPausingActivity != null) {
//如果要pause一个Activity时,已经有一个Activity在pause还未完成
//(pause完成的话mPausingActivity 为null),那么抛出一个异常。
Slog.e(TAG, "Trying to pause when pause is already pending for "
+ mPausingActivity, new RuntimeException("here").fillInStackTrace());
}
ActivityRecord prev = mResumedActivity;//保存正在显示的app
//mResumedActivity中保存的是当前resume的Activity,
// pause的对象肯定是当前的resume的Activity,如果当前没有resume对象,
//这种情况也就是系统启动第一个Activity才有的情况,此时就直接resume Activity栈中的顶层Activity。
if (prev == null) {
Slog.e(TAG, "Trying to pause when nothing is resumed",
new RuntimeException("here").fillInStackTrace());
mStackSupervisor.resumeTopActivitiesLocked();
return;
}
if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
//当前resume的Activity要被pause掉了,那么mResumedActivity必然要重置为null了?
// 同时mPausingActivity指向当前resumed的Activity。
mResumedActivity = null;
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) !=
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != ? prev : null;
prev.state = ActivityState.PAUSING;
prev.task.touchActiveTime();
clearLaunchTime(prev);
/// M: Add for launch time enhancement @{
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "amScreenCapture");
if (!prev.isHomeActivity()) {
prev.updateThumbnail(screenshotActivities(prev), null);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
/// @}
stopFullyDrawnTraceIfNeeded();
mService.updateCpuStats();
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
/// M: AMS log enhancement @{
if (!ActivityManagerService.IS_USER_BUILD)
Slog.d(TAG, "ACT-AM_PAUSE_ACTIVITY " + prev );
/// @}
mService.updateUsageStats(prev, false);
//调用当前Activity所在进程的schedulePauseActivity函数
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags);
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
if (!mService.isSleepingOrShuttingDown()) {
mStackSupervisor.acquireLaunchWakelock();
//获取一个唤醒锁,防止系统睡眠,获取唤醒锁时要注意释放
}
if (mPausingActivity != null) {
// Have the window manager pause its key dispatching until the new
// activity has started. If we're pausing the activity just because
// the screen is being turned off and the UI is sleeping, don't interrupt
// key dispatch; the same activity will pick it up again on wakeup.
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();//暂停按键下发通道,直到新的activity起来
} else {
if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
}
// Schedule a pause timeout in case the app doesn't respond.
// We don't give it much time because this directly impacts the
// responsiveness seen by the user.
Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
msg.obj = prev;
prev.pauseTime = SystemClock.uptimeMillis();
mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
//设置超时500ms,告诉应用尽快完成相关操作
//⑨post一个PAUSE_TIMEOUT_MSG消息,为什么要post这么个消息
//,是因为如果无法完成paused前一个Activity,那么就无法start下一个Activity
//,这个超时消息是防止异常导致无法及时start下一个Activity,在超时消息处理函数中肯定有start next Activity的逻辑。
if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
} else {
// This activity failed to schedule the
// pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
}
}
startPausingLocked将调用应用进程的schedulePauseActivity函数,并设置500毫秒的超时时间,所以应用进程需尽快完成相关处理。和scheduleLaunchActivity一样,schedulePauseActivity将向ActivityThread主线程发送PAUSE_ACTIVITY消息,最终该消息由handlePauseActivity来处理。
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
if (userLeaving) {
performUserLeavingActivity(r);//告诉用户要离开当前activity,会调用onUserLeaveHint函数
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb()); //调用Activity的onPause函数
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
}
}
}
final void activityPausedLocked(IBinder token, boolean timeout) {
if (DEBUG_PAUSE) Slog.v(
TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
/// M: AMS log enhancement @{
if (!ActivityManagerService.IS_USER_BUILD)
Slog.d(TAG, "ACT-paused: token=" + token + ", timeout=" + timeout);
/// @}
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
//从消息队列中撤销PAUSE_TIMEOUT_MSG消息
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
r.state = ActivityState.PAUSED;//设置 ActivityRecord 状态
completePauseLocked();//完成本次 暂停
private void completePauseLocked() {
ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
if (prev != null) {
if (prev.finishing) {
if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);//结束这个 ActivityRecord
} else if (prev.app != null) {
if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
if (prev.waitingVisible) {
prev.waitingVisible = false;//因为此Activity要暂停,所以不在等待可见。只有要显示Activity 的waitingVisible为true
mStackSupervisor.mWaitingVisibleActivities.remove(prev);
if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
TAG, "Complete pause, no longer waiting: " + prev);
}
if (prev.configDestroy) {
destroyActivityLocked(prev, true, false, "pause-config");
} else {
mStackSupervisor.mStoppingActivities.add(prev);
if (mStackSupervisor.mStoppingActivities.size() > ||
prev.frontOfTask && mTaskHistory.size() <= ) {
if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
mStackSupervisor.scheduleIdleLocked();
//如果被暂停的activity超过3个或者 当前activity是root activity且当前task是最后一个task
if (!ActivityManagerService.IS_USER_BUILD)
Slog.d(TAG, "ACT-IDLE_NOW_MSG from completePauseLocked for mStoppingActivities.size() > 3");
/// @}
} else {
mStackSupervisor.checkReadyForSleepLocked();
}
}
} else {
if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
prev = null;
}
mPausingActivity = null;
}
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) {//如果系统不是在将要睡眠和关闭
mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);//启动在栈顶的Activity
} else {
mStackSupervisor.checkReadyForSleepLocked();
ActivityRecord top = topStack.topRunningActivityLocked(null);//启动在栈顶的Activity
if (top == null || (prev != null && top != prev)) {
mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
}
}
if (prev != null) {
/// M: it's to avoid deadlock in AMS/WMS, Ref: ALPS00231742 @{
//prev.resumeKeyDispatchingLocked();
new myThread(prev).start();
/// @}
if (prev.app != null && prev.cpuTimeAtResume >
&& mService.mBatteryStatsService.isOnBattery()) {
long diff;
synchronized (mService.mProcessCpuThread) {
diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
- prev.cpuTimeAtResume;
}
if (diff > ) {
BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
synchronized (bsi) {
BatteryStatsImpl.Uid.Proc ps =
bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
prev.info.packageName);
if (ps != null) {
ps.addForegroundTimeLocked(diff);
}
}
}
}
prev.cpuTimeAtResume = ; // reset it
}
}