热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

进程被杀Task被移除

现象Kill查杀Task被移除当Task处于前台&Task中唯一的activity不处于onStop(可能处于onResumeonPause等)状态




现象


Kill查杀

image.png


Task被移除

当Task处于前台&Task中唯一的activity不处于onStop(可能处于onResume/onPause等)状态时,当前进程被kill查杀,当前activity会被finish导致task中因无activity而被移除。

12-08 15:20:54.991 18018 18018 I wm_on_resume_called: [0,170803945,com.zhihu.android.app.ui.activity.MainActivity,RESUME_ACTIVITY,23]
12-08 15:27:27.763 3076 4898 I am_proc_died: [0,18018,com.zhihu.android,0,2]
12-08 15:27:27.786 3076 4898 I wm_finish_activity: [0,170803945,51,com.zhihu.android/.app.ui.activity.MainActivity,proc died without state saved]
12-08 15:27:27.792 3076 4898 I wm_task_removed: [51,removeChild:removeChild last r=ActivityRecord{a2e42e9 u0 com.zhihu.android/.app.ui.activity.MainActivity} t-1 f}} in t=Task{c3e28 #51 type=standard A=10251:com.zhihu.android U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0}]
12-08 15:27:27.792 3076 4898 I wm_task_removed: [51,removeChild]

Task不被移除


task处于后台-无特殊操作

activity处于onStop状态,进程被杀不做处理

12-08 15:36:55.176 29395 29395 I wm_on_stop_called: [0,17359319,com.zhihu.android.app.ui.activity.MainActivity,STOP_ACTIVITY_ITEM,328]
12-08 15:39:49.161 3076 3160 I am_proc_died: [0,29395,com.zhihu.android,700,15]

task处于前台-进程可能会被再次拉起

进程被杀时,onResume/onPause的activity被finish,onStop不做处理;且进程会因底下的页面会被重新拉起。

12-08 15:42:06.824 18020 18020 I wm_on_resume_called: [0,263348372,com.zhihu.android.mix.activity.ContentMixProfileActivity,RESUME_ACTIVITY,29]
12-08 15:42:07.182 18020 18020 I wm_on_stop_called: [0,17359319,com.zhihu.android.app.ui.activity.MainActivity,STOP_ACTIVITY_ITEM,4]
// 进程被杀
12-08 15:42:49.228 3076 6405 I am_proc_died: [0,18020,com.zhihu.android,0,2]
// top resume被finish
12-08 15:42:49.263 3076 6405 I wm_finish_activity: [0,263348372,53,com.zhihu.android/.mix.activity.ContentMixProfileActivity,proc died without state saved]
// top底下的activity变为top,且进程因top-activity被重新拉起
12-08 15:42:49.296 3076 3193 I am_proc_start: [0,26378,10251,com.zhihu.android,top-activity,{com.zhihu.android/com.zhihu.android.app.ui.activity.MainActivity}]
12-08 15:42:49.400 3076 6405 I wm_restart_activity: [0,17359319,53,com.zhihu.android/.app.ui.activity.MainActivity]
12-08 15:42:49.402 3076 6405 I wm_set_resumed_activity: [0,com.zhihu.android/.app.ui.activity.MainActivity,minimalResumeActivityLocked - onActivityStateChanged]
12-08 15:42:49.877 26378 26378 I wm_on_application_create_called: [0,com.zhihu.android,219]
12-08 15:42:50.487 26378 26378 I wm_on_create_called: [0,17359319,com.zhihu.android.app.ui.activity.MainActivity,performCreate,563]
12-08 15:42:50.538 26378 26378 I wm_on_start_called: [0,17359319,com.zhihu.android.app.ui.activity.MainActivity,handleStartActivity,50]

ForceStop查杀

在这里插入图片描述

无论Task前台与否,Task中所有activity都会被finish,最后task被移除

12-08 15:59:09.912 26388 26388 I wm_on_resume_called: [0,155633411,com.zhihu.android.mix.activity.ContentMixProfileActivity,RESUME_ACTIVITY,26]
12-08 15:59:10.326 26388 26388 I wm_on_stop_called: [0,129034736,com.zhihu.android.app.ui.activity.MainActivity,STOP_ACTIVITY_ITEM,11]
12-08 15:59:56.503 3076 7901 I wm_finish_activity: [0,155633411,54,com.zhihu.android/.mix.activity.ContentMixProfileActivity,proc died without state saved]
12-08 15:59:56.518 3076 7901 I wm_finish_activity: [0,129034736,54,com.zhihu.android/.app.ui.activity.MainActivity,proc died without state saved]
12-08 15:59:56.522 3076 7901 I wm_task_removed: [54,removeChild:removeChild last r=ActivityRecord{7b0e9f0 u0 com.zhihu.android/.app.ui.activity.MainActivity} t-1 f}} in t=Task{ade072f #54 type=standard A=10251:com.zhihu.android U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0}]
12-08 15:59:56.522 3076 7901 I wm_task_removed: [54,removeChild]

原理


Kill查杀


mHaveState 的赋值

代表是否保留上次保存的activity状态,初始值是true;;onResume后赋值为false;onStop后赋值为true

private boolean mHaveState = true;
/** Update the saved state of an activity. */
void setSavedState(@Nullable Bundle savedState) {
mIcicle = savedState;
mHaveState = mIcicle != null;
}

在这里插入图片描述


activity被finish的情况


  • 执行了onResume & 没有声明stateNotNeeded=true & state不为RESTARTING_PROCESS
  • finishing 为true
  • crash次数超过2次&最近一次crash在1min内

handleAppDied

进程被kill后ams收到死亡回调后会进行一些清理操作,清理包括四大组件和进程相关信息,这里只讲activity相关。
Activity 被移除后如果Task中没有其他activity,则task也会被移除
在这里插入图片描述

void handleAppDied() {
final boolean remove;
.......
// onResume执行完mHaveState为false
// 如果是forceStop查杀,此处finishing为true
} else if ((!mHaveState && !stateNotNeeded
&& !isState(State.RESTARTING_PROCESS)) || finishing) {
remove = true;
} else if (!mVisibleRequested && launchCount > 2
&& lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
remove = true;
} else {
// The process may be gone, but the activity lives on!
remove = false;
}
if (remove) {
if (!finishing || (app != null && app.isRemoved())) {
Slog.w(TAG, "Force removing " + this + ": app died, no saved state");
EventLogTags.writeWmFinishActivity(mUserId, System.identityHashCode(this),
task != null ? task.mTaskId : -1, shortComponentName,
"proc died without state saved");
}
} else {
nowVisible = mVisibleRequested;
}
mTransitionController.requestCloseTransitionIfNeeded(this);
cleanUp(true /* cleanServices */, true /* setState */);
if (remove) {
.......
removeFromHistory("appDied");
}
}

进程被重新拉起

在这里插入图片描述


ForceStop查杀

forceStop时传入killPackageProcessesLSP的参数setRemoved为true,会提前将相关进程对应的Activity mark finish(i避免进程又因为next top被重新拉起),等待进程死亡时去执行finish操作。

boolean handleAppDied() {
mAtm.mTaskSupervisor.removeHistoryRecords(this);
.......
// forceStop 查杀,会将所有的activity都标记为finihsing
if (isRemoved()) {
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.
hasVisibleActivities = true;
}
final TaskFragment taskFragment = r.getTaskFragment();
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;
}

结论&建议

如果想进程被杀时task也同步被移除:


  1. ActivityManager#forceStopPackage()

@SystemApi
// 注意声明权限
@RequiresPermission(Manifest.permission.FORCE_STOP_PACKAGES)
public void forceStopPackage(String packageName) {
forceStopPackageAsUser(packageName, mContext.getUserId());
}

  1. ActivityTaskManager#removeTask

注意此种方式会同步移除最近任务中的卡片

/** Removes task by a given taskId */
// 声明权限
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
public boolean removeTask(int taskId) {
try {
return getService().removeTask(taskId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}






推荐阅读
author-avatar
修魔海的传说
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有