当前位置:网站首页>restartProcessIfVisible的流程
restartProcessIfVisible的流程
2022-06-30 15:48:00 【AmyTan小小燕】
主要流程如下:
- 当前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;
}
边栏推荐
- HMS Core音频编辑服务3D音频技术,助力打造沉浸式听觉盛宴
- register_chrdev和cdev_init cdev_add用法区别
- Mathematical modeling for war preparation 36 time series model 2
- Halcon knowledge: matrix topic [02]
- 招标公告:2022年台州联通Oracle一体机和数据库维保服务项目
- Interesting research on mouse pointer interaction
- Mysql8.0 method and steps for enabling remote connection permission
- 云技能提升好伙伴,亚马逊云师兄今天正式营业
- Observation cloud reached in-depth cooperation with tdengine to optimize enterprise cloud experience
- 抖快B为啥做不好综艺
猜你喜欢

ArcMap operation series: 80 plane to latitude and longitude 84

go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)

【Verilog基础】关于Clock信号的一些概念总结(clock setup/hold、clock tree、clock skew、clock latency、clock transition..)
mysql8报错:ERROR 1410 (42000): You are not allowed to create a user with GRANT解决办法

香港回归25周年 香港故宫博物馆正式开放成文化新地标

Hundreds of lines of code to implement a JSON parser

Good partner for cloud skill improvement, senior brother cloud of Amazon officially opened today

新茶饮“死去活来”,供应商却“盆满钵满”?

牛客网:乘积为正数的最长连续子数组
![[unity ugui] scrollrect dynamically scales the grid size and automatically locates the middle grid](/img/c9/ff22a30a638b5d9743d39e22ead647.png)
[unity ugui] scrollrect dynamically scales the grid size and automatically locates the middle grid
随机推荐
dart:字符串replace相关的方法解决替换字符
招标公告:天津市住房公积金管理中心数据库一体机及数据库软件项目(预算645万)
2020 Blue Bridge Cup group B - move bricks - (greedy sorting +01 backpack)
Half year inventory of new consumption in 2022: the industry is cold, but these nine tracks still attract gold
Does flinkcdc have to be a clustered version if the monitored database is Mongo
BC1.2 PD协议
观测云与 TDengine 达成深度合作,优化企业上云体验
Yunhe enmo won the bid for Oracle maintenance project of Tianjin Binhai rural commercial bank in 2022-2023
halcon知识:区域专题【07】
Raft介绍
【微信小程序】小程序的宿主环境
How the edge computing platform helps the development of the Internet of things
Mysql8 error: error 1410 (42000): you are not allowed to create a user with grant solution
【机器学习】K-means聚类分析
MySQL开放远程连接权限的两种方法
POJ Project Summer
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
Three development trends of enterprise application viewed from the third technological revolution
HMS Core音频编辑服务3D音频技术,助力打造沉浸式听觉盛宴
Rongsheng biology rushes to the scientific innovation board: it plans to raise 1.25 billion yuan, with an annual revenue of 260million yuan