final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
r.startFreezingScreenLocked(app, 0);//冻结屏幕
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 < 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<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(0).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) != 0) {
// 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 pendingResults,
List 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 != 0) {
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 stops = null;
ArrayList finishes = null;
ArrayList startingUsers = null;
int NS = 0;
int NF = 0;
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(4));
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);//移除IDLE_TIMEOUT_MSG 消息
r.finishLaunchTickingLocked();
if (fromTimeout) {
reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
}
// 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, 0);
}
// Atomically retrieve all of the other things to do.
stops = processStoppingActivitiesLocked(true);// 得到因本次启动而被 pause 的 Activity
NS = stops != null ? stops.size() : 0;
if ((NF=mFinishingActivities.size()) > 0) {
finishes = new ArrayList(mFinishingActivities);
mFinishingActivities.clear();
}
final ArrayList thumbnails;
final int NT = mCancelledThumbnails.size();
if (NT > 0) {
thumbnails = new ArrayList(mCancelledThumbnails);
mCancelledThumbnails.clear();
} else {
thumbnails = null;
}
if (isFrontStack(mHomeStack)) {
booting = mService.mBooting;
mService.mBooting = false;
}
if (mStartingUsers.size() > 0) {
startingUsers = new ArrayList(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 = 0; 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 = 0; 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 = 0; 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 = 0; 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) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? 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() > 3 ||
prev.frontOfTask && mTaskHistory.size() <= 1) {
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 > 0
&& mService.mBatteryStatsService.isOnBattery()) {
long diff;
synchronized (mService.mProcessCpuThread) {
diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
- prev.cpuTimeAtResume;
}
if (diff > 0) {
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 = 0; // reset it
}
}