主要流程如下:
- 当前Activity前台可见,先让其app执行onStop以及onSaveInstanceState保存数据;不可见直接查杀
- Activity告知system server 执行完stop,系统查杀进程;
- 进程被杀处理handleAppDied时,当前activity在前台,所以会通过activity拉起进程。
/**
* Request the process of the activity to restart with its saved state (from
* {@link android.app.Activity#onSaveInstanceState}) if possible. It also forces to recompute
* the override configuration. Note if the activity is in background, the process will be killed
* directly with keeping its record.
*/
void restartProcessIfVisible() {
// 打印相关log
Slog.i(TAG, "Request to restart process of " + this);
// Reset the existing override configuration so it can be updated according to the latest
// configuration.
// 清空原生内缩
clearSizeCompatMode();
// 如果activity对应的进程不存在则直接返回
if (!attachedToProcess()) {
return;
}
// The restarting state avoids removing this record when process is died.
// QCOM ADD:
callServiceTrackeronActivityStatechange(RESTARTING_PROCESS, true);
// 设置actiivty的状态为RESTARTING_PROCESS,后面根据这个状态查杀对应的进程
setState(RESTARTING_PROCESS, "restartActivityProcess");
// activity没有处于resume状态
if (!mVisibleRequested || mHaveState) {
// Kill its process immediately because the activity should be in background.
// The activity state will be update to {@link #DESTROYED} in
// {@link ActivityStack#cleanUp} when handling process died.
// post到display线程去执行
mAtmService.mH.post(() -> {
final WindowProcessController wpc;
synchronized (mAtmService.mGlobalLock) {
// 如果app进程不存在或者app的procState <= 6(即activity没有可见但app进程又比较重要 ), 不予处理
if (!hasProcess()
|| app.getReportedProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND) {
return;
}
wpc = app;
}
//activity处于后台直接 单独查杀进程(不清Task和system server保存的相关app数据),调用ProcessList的removeProcessLocked方法
mAtmService.mAmInternal.killProcess(wpc.mName, wpc.mUid, "resetConfig");
});
return;
}
// 开始冻结屏幕
if (getParent() != null) {
startFreezingScreen();
}
// The process will be killed until the activity reports stopped with saved state (see
// {@link ActivityTaskManagerService.activityStopped}).
try {
// 先让当前Activity执行onStop以让app保存相关数据到bundle state中
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
StopActivityItem.obtain(0 /* configChanges */));
} catch (RemoteException e) {
Slog.w(TAG, "Exception thrown during restart " + this, e);
}
// 重启超时是2s,activitystop回调后会取消超时消息,超时后直接查杀进程
mTaskSupervisor.scheduleRestartTimeout(this);
}
@Override
public void activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState,
CharSequence description) {
if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
// Refuse possible leaked file descriptors.
if (icicle != null && icicle.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
}
final long origId = Binder.clearCallingIdentity();
String restartingName = null;
int restartingUid = 0;
final ActivityRecord r;
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityStopped");
// token对应的ActivityRecord存在且没有被从Task中移除
r = ActivityRecord.isInRootTaskLocked(token);
if (r != null) {
// ActivityRecord对应的进程存在& ActivityRecord的状态为RESTARTING_PROCESS
if (r.attachedToProcess() && r.isState(Task.ActivityState.RESTARTING_PROCESS)) {
// The activity was requested to restart from
// {@link #restartActivityProcessIfVisible}.
// 先保存下相关的name和uid,因为执行完r.activityStopped后,actiivty的state会变为STOPPED
restartingName = r.app.mName;
restartingUid = r.app.mUid;
}
// 执行Activity stop
r.activityStopped(icicle, persistentState, description);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
if (restartingName != null) {
// In order to let the foreground activity can be restarted with its saved state from
// {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed
// until the activity reports stopped with the state. And the activity record will be
// kept because the record state is restarting, then the activity will be restarted
// immediately if it is still the top one.
// 移除2s的超时
mTaskSupervisor.removeRestartTimeouts(r);
// 查杀进程
mService.mAmInternal.killProcess(restartingName, restartingUid,
"restartActivityProcess");
}
mService.mAmInternal.trimApplications();
Binder.restoreCallingIdentity(origId);
}
@Override
public void killProcess(String processName, int uid, String reason) {
synchronized (ActivityManagerService.this) {
final ProcessRecord proc = getProcessRecordLocked(processName, uid);
if (proc != null) {
mProcessList.removeProcessLocked(proc, false /* callerWillRestart */,
true /* allowRestart */, ApplicationExitInfo.REASON_OTHER, reason);
}
}
}
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public void handleAppDied(WindowProcessController wpc, boolean restarting,
Runnable finishInstrumentationCallback) {
synchronized (mGlobalLockWithoutBoost) {
mTaskSupervisor.beginDeferResume();
final boolean hasVisibleActivities;
try {
// Remove this application's activities from active lists.
// 是否有可见页面
hasVisibleActivities = wpc.handleAppDied();
} finally {
mTaskSupervisor.endDeferResume();
}
if (!restarting && hasVisibleActivities) {
deferWindowLayout();
try {
if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) {
// If there was nothing to resume, and we are not already restarting
// this process, but there is a visible activity that is hosted by the
// process...then make sure all visible activities are running, taking
// care of restarting this process.
mRootWindowContainer.ensureActivitiesVisible(null, 0,
!PRESERVE_WINDOWS);
}
} finally {
continueWindowLayout();
}
}
// MIUI ADD: START
if (MiuiAppContinuityStub.get().isEnabled()) {
ActivityTaskManagerServiceStub.get().handleAppDiedReport(wpc.mName);
}
ActivityTaskManagerServiceStub.get().restartSubScreenUiIfNeeded(wpc.mInfo, "app died");
// END
}
if (wpc.isInstrumenting()) {
finishInstrumentationCallback.run();
}
}
/**
* Clean up the activities belonging to this process.
*
* @return {@code true} if the process has any visible activity.
*/
boolean handleAppDied() {
// 从stopping列表和finishing列表中移除掉当前app的所有activity
mAtm.mTaskSupervisor.removeHistoryRecords(this);
boolean hasVisibleActivities = false;
// 是否有正在destroying状态的activity
final boolean hasInactiveActivities =
mInactiveActivities != null && !mInactiveActivities.isEmpty();
// 当前app有任何状态的activity,新建一个数组
final ArrayList<ActivityRecord> activities =
(mHasActivities || hasInactiveActivities) ? new ArrayList<>() : mActivities;
if (mHasActivities) {
activities.addAll(mActivities);
}
if (hasInactiveActivities) {
// Make sure that all activities in this process are handled.
activities.addAll(mInactiveActivities);
}
// 如果是force stop查杀/app crash 太多次,需要将所有activity标记为finishing,避免进程因activity被重复拉起
if (isRemoved()) {
// The package of the died process should be force-stopped, so make its activities as
// finishing to prevent the process from being started again if the next top (or being
// visible) activity also resides in the same process. This must be done before removal.
for (int i = activities.size() - 1; i >= 0; i--) {
activities.get(i).makeFinishingLocked();
}
}
for (int i = activities.size() - 1; i >= 0; i--) {
final ActivityRecord r = activities.get(i);
if (r.mVisibleRequested || r.isVisible()) {
// While an activity launches a new activity, it's possible that the old activity
// is already requested to be hidden (mVisibleRequested=false), but this visibility
// is not yet committed, so isVisible()=true.
// 是否有可见的activity (可能pause 或 resume状态)
hasVisibleActivities = true;
}
final TaskFragment taskFragment = r.getTaskFragment();
// 将Task中的正在pausing的activity也算做可见
if (taskFragment != null) {
// There may be a pausing activity that hasn't shown any window and was requested
// to be hidden. But pausing is also a visible state, it should be regarded as
// visible, so the caller can know the next activity should be resumed.
hasVisibleActivities |= taskFragment.handleAppDied(this);
}
r.handleAppDied();
}
// 清除操作
clearRecentTasks();
clearActivities();
return hasVisibleActivities;
}