进程被杀Task被移除

news2025/1/11 21:54:12

现象

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();
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows11去掉桌面快捷方式箭头

有部分强迫症用户,看到桌面每个图标都有一个小箭头,只想去掉看着舒服一点 但是Win10的大部分脚本都不能使用了,而且有可能导致桌面图标显示异常,不建议大家再去用脚本尝试(Win11也有脚本,但是随便更新版本&#xff0c…

深入理解Kafka Producer内部机制

总的来说,Kafka Producer是将数据发送到kafka集群的客户端。其组成部分如下图所示: 基本组件: Producer Metadata——管理生产者所需的元数据:集群中的主题和分区、充当分区领导者的代理节点等。Partitioner——计算给定记录的分…

Pygame入门-游戏代码结构及背景轮播、声音音效及图像动态效果

一、游戏代码结构 代码结构是代码的组织方式,也是游戏编程的思考框架。pygame官方文档中给出了以下建议,将游戏代码结构分为以下六个部分。 1导入游戏模块。 2资源处理类;定义一些类来处理最基本的资源,包括加载图像和声音,连接和…

C#(csharp)这门语言的优势在哪?

确实有不少人因为unity入坑C#,unity刚开始使用的语言也有很多,比如Unity(一种Java的扩展)或者Boo(一种受Python启发的语言),但C#坚持至今甚至成为unity使用主流,C#当然有它的优点。 …

实测 ChatGPT 编程效果被其发现,这波我先站队 Stack Overflow

本文对 ChatGPT 解答编程问题的情况进行了测试。测试了不同难度的问题,并对 ChatGPT 的回答结果进行了鉴别。测试结果表明,ChatGPT 在解答简单的编程问题时表现较为出色,但在解决复杂的问题时则不太理想。因此,也总结出了如何更好…

Vulnhub靶机:SICKOS_ 1.1

目录介绍信息收集主机信息探测主机信息探测网站探测Getshell敏感信息收集SUDO提权第2种通关思路nikto扫描站点验证破壳漏洞破壳漏洞利用计划任务提权修复文件内容错乱 & 提权总结介绍 系列:SickOs(此系列共2台) 发布日期:201…

springboot+netty实现站内消息通知(完整代码)

代码用到的组件介绍 ChannelInitializer 见名知意,就是channel 初始化器,当每个客户端创建连接时这里面的代码都会执行一遍。由于,连接建立之后,这个channel就会常驻内存,所以这里就有个值得思考的问题: …

【vue核心】1.vue简介

1. 官网 英文官网: https://vuejs.org/ 中文官网: https://cn.vuejs.org/ 2. 介绍与描述 动态构建用户界面的渐进式 JavaScript 框架 作者: 尤雨溪 3. Vue 的特点 遵循 MVVM 模式 编码简洁, 体积小, 运行效率高, 适合移动/PC 端开发 它本身只关注UI, 也可以引入其它第三…

新冠疫苗预约小程序设计与实现的源码+文档

摘 要 网络的广泛应用给生活带来了十分的便利。所以把新冠疫苗预约管理与现在网络相结合,利用java技术建设新冠疫苗预约小程序,实现新冠疫苗预约的信息化。则对于进一步提高新冠疫苗预约管理发展,丰富新冠疫苗预约管理经验能起到不少的促进…

数据库挖矿系列-优化器设计探索穿越之旅

作者:王晨 阿里云数据库产品团队 前言 引用来自百度百科的话:在数据库技术发展历史上,1970 年是发生伟大转折的一年,因为这一年的6月,IBM的圣约瑟研究实验室的高级研究员Edgar Frank Codd在Communications of ACM 上…

微信中使用ChatGPT

ChatGPT 微信 Bot1. Ubuntu2. 卸载旧版本3. apt 安装4. 添加软件源的GPG密钥5. 添加docker源到sources.list6. 安装 docker7. 启动 docker8. 建立docker用户组9. 测试10. wechat-chatgpt 搭建11. 获取 会话令牌12. 运行13. 使用微信小号扫码登录14. 重新登录14.1 停止运行容器1…

【Python项目】Python实现点选验证码识别, 模拟B站登陆 | 附源码 学习资料

前言 halo,包子们下午好 今天小编带大家是想b站模拟登陆,Python实现验证码识别 废话不多说,直接开整 相关文件 关注小编,私信小编领取哟! 当然别忘了一件三连哟~~ 公众号:Python日志 源码点击蓝色字体领…

Docker Desktop下部署springboot项目

一、前言 本文是基于windows10版本下的docker desktop来演示的,所以你需要自行安装docker desktop,可以是windows,也可以是mac,根据自己的电脑进行选择即可。 二、创建springboot项目 创建一个springboot web项目,这个比较简单&#xff0c…

Vector-常用CAN工具 - CANoe入门到精通_04

前面已经介绍了Network Node节点的创建和配置,我想大家如果仔细研究下这块基本没什么问题,但是针对相应的CAPL编程该如何去做呢?今天这篇文章就是我们专门介绍在Network Node节点中常用的一些操作函数和使用技巧。 五、 Network Node相关CAPL…

如何在 Canvas 上实现图形拾取?

大家好,我是前端西瓜哥,今天来和大家说说 canvas 怎么做图形拾取。 图形拾取,指的是用户通过鼠标或手指在图形界面上能选中图形的能力。图形拾取技术是之后的高亮图形、拖拽图形、点击触发事件的基础。 canvas 作为一个过于朴实无华的绘制工…

【软件测试】老板:你测试,我放心。测试人的成功就是不做测试?

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 测试没价值&#xf…

[附源码]计算机毕业设计的党务管理系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Arco Pro最佳实践,路由与菜单

Arco Pro最佳实践,路由与菜单1.路由2.菜单3.测试1.路由 路由通常都和菜单绑定在一起,为了减少维护的量,Arco直接通过路由表生成了菜单。 首先,需要先了解一下路由表的配置 现在我们来解析一下仪表盘的路由代码(dash…

Ranger集成Solr

前言 对已经在正常使用的Ranger开启Solr存储审计日志。 可以手动安装或者使用ranger admin自带的solr安装程序来安装。当然官网也说了,用户可以选择手动安装然后集成,只要你足够勇敢 :) 我们这里选择使用Ranger自带的安装程序来…

深度学习之:强化学习 Reinforcement Learning

文章目录认识强化学习Sparse RewardSupervised Learning v.s. RLRL 玩游戏Policy-based & Value-basedPolicy-based训练模型的三步骤定义目标函数衡量目标函数的好坏RL 的目标函数的好坏(reward 总和的期望)如何求得 Rθˉ\bar{R_{\theta}}Rθ​ˉ​…