转自:http://zhengxiaoyong.me/2016/09/05/Android%E8%BF%90%E8%A1%8C%E6%97%B6Crash%E8%87%AA%E5%8A%A8%E6%81%A2%E5%A4%8D%E6%A1%86%E6%9E%B6-Recovery/

简介

App Crash的恢复,这个想法很早之前就有,目前有些时间就实现了一把,主要是对App运行时发生Crash后,对Activity的堆栈和数据进行恢复,或者重启应用,或者重启并清空缓存,避免因本地的数据类型或格式错误而导致App在读取时一直Crash,Debug模式还包括Crash信息的显示和保存,便于在开发、测试时查看相应CrashInfo

Crash的处理

对于应用的Crash,一般的做法我们往往都是实现个自定义UncaughtExceptionHandler,而这个自定义的CustomUncaughtHandler我们一般都用于捕捉Crash信息进行上报和监控是否发生Crash,还有一个作用就是可以屏蔽系统默认的Crash对话框,也就是拦截Crash后不把系统默认的UncaughtHandler设置进去,而是直接进行KillProcess,这个过程就是屏蔽了系统的默认Crash处理流程,原因是系统的处理其中在AMS的crashApplication()中会执行这么一段代码:

1
2
3
4
5
6
7
Message msg = Message.obtain();
msg.what = SHOW_ERROR_MSG;
HashMap data = new HashMap();
data.put("result", result);
data.put("app", r);
msg.obj = data;
mUiHandler.sendMessage(msg);

发送一个显示Dialog的消息,之后便创建一个AppErrorDialog进行显示。

当然还有另外一种屏蔽系统默认ErrorDialog的方法,就是对AMP进行Hook,拦截handleApplicationCrash()方法后进行KillProcess,这样的话永远都将不会出现系统默认对话框,即使把系统默认的设置进去了,这个方法建议App内对AMP进行了Hook的做,其它App反而只为实现这个小功能而进行Hook成本太高,还是用自定义的做法进行屏蔽。

Recovery

Crash处理流程

对于Recovery,在应用发生Crash时,会进入一个Recovery界面,在该界面可以进行界面的恢复、应用的重启,或进入debug模式进行Crash信息的查看与保存

接入

请戳这里

RecoveryActivity

在应用发生Crash后,将进入RecoveryActivity界面

ActivityStack的恢复

对于恢复界面,默认是恢复整个Activity的堆栈,以便保护用户之前的数据

当应用在前台时崩溃无非就三种:
1、界面一创建就崩溃,可能在onCreate等方法中读取数据造成的Crash
2、界面创建且绘制完成正常显示,在用户执行某个操作,如点击按钮执行某个操作等造成的Crash
3、其它异步线程、服务等在后台执行任务时导致的Crash

上面的情况都应恢复绘制完成后的界面,也就是栈顶Activity是在Crash之前用户所看到的界面,而之前创建且未销毁的Activity也应该进行恢复。

当应用在后台时:
1、进程未挂,无非就是异步线程、server等后台任务发生异常时导致的Crash
2、进程已挂,进程被360等工具杀死了,常见的是push过来了然后唤起App进程,在解析push信息时候导致Crash

上面的情况App在后台时导致的Crash,Recovery提供了一个参数(recoverInBackgroud),用来设置是否在后台Crash时进行恢复。

ActivityStack恢复的操作,都是先恢复栈中的Activity,无Activity时则重启应用

主页的回退

在进行恢复Activity时,如果只是恢复栈顶Activity,当用户在这个界面不进行跳转操作而是直接按返回键,这将导致直接退出程序,所以对于这个情况应该是回退到应用的主页,Recovery中有个参数mainPage,如果设置了就表示需要回退到主页,没有设置则不进行回退

这个过程中涉及到获取App内Activity栈内的数量和栈底Activity,是开发人员应该都知道获取这两个信息是通过getRunningTasks来获取,不过可惜,在5.0以后Google对权限进行了收敛,目地是保护App的信息安全,这个方法在5.0以后将失效,所以需要另外一种方法进行兼容,于是乎看6.0源码又发现Google在5.0收敛了整个权限,导致本App的都获取不到,但是在6.0又放出来了,不过只能获取本应用的数据,所以兼容的策略是5.0~6.0自己维护一个ActivityStack

连续Crash的处理

如果一分钟内进行了两次恢复后还导致Crash,则不进行恢复而是重启应用,或者重启并清空缓存,以便恢复App刚安装时的状态

静默恢复

对于应用运行时发生Crash后的恢复,默认是显示RecoveryActivity,也就是上图的界面来让用户选择是否需要进行恢复,同时也支持静默恢复,也就是不显示界面,在发生Crash后根据所配置参数自动的恢复(重启、恢复ActivityStack、恢复栈顶Activity、重启并清空缓存)

无图言屌

下面是效果图:

静默恢复的效果图:

项目地址

欢迎star或提建议

Android运行时Crash自动恢复框架-Recovery的更多相关文章

  1. Angular4项目运行时URL自动加#方法

    import {HashLocationStrategy , LocationStrategy} from '@angular/common'; @NgModule({   declarations: ...

  2. Android执行时ART载入类和方法的过程分析

    在前一篇文章中.我们通过分析OAT文件的载入过程,认识了OAT文件的格式,当中包括了原始的DEX文件. 既然ART运行时运行的都是翻译DEX字节码后得到的本地机器指令了.为什么还须要在OAT文件里包括 ...

  3. 我为Dexposed续一秒——论ART上运行时 Method AOP实现

    转载于:http://weishu.me/2017/11/23/dexposed-on-art/ 两年前阿里开源了 Dexposed 项目,它能够在Dalvik上无侵入地实现运行时方法拦截,正如其介绍 ...

  4. iOS运行时Runtime浅析

    运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...

  5. Android免Root无侵入AOP框架Dexposed

    Dexposed框架是阿里巴巴无线事业部近期开源的一款在Android平台下的免Root无侵入运行期AOP框架,该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事 ...

  6. Android平台下Dalvik层hook框架ddi的研究

    通过adbi,可以对native层的所有代码进行hook.但对于Android系统来说,这还远远不够,因为很多应用都还是在Dalvik虚拟机中运行的. 那么,有没有什么办法可以对Dalvik虚拟机中跑 ...

  7. runtime运行时

    /** * Describes the instance variables declared by a class. * * @param cls The class to inspect. * @ ...

  8. Java程序运行时,数据都保存到什么地方?

    程序运行时,我们最好对数据保存到什么地方做到心中有数.特别要注意的是内存的分配.有六个地方都可以保存数据: 寄存器 这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部.然而,寄存器 ...

  9. 《转》.NET开源核心运行时,且行且珍惜

    转载自infoQ 背景 InfoQ中文站此前报道过,2014年11月12日,ASP.NET之父.微软云计算与企业级产品工程部执行副总裁Scott Guthrie,在Connect全球开发者在线会议上宣 ...

随机推荐

  1. mysql 触发器(trigger) 总结

    触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/befo ...

  2. EntityFramework 学习 一 CRUD using Stored Procedure: 使用存储过程进行CRUD操作

    我们先创建如下3个存储过程 1.Sp_InsertStudentInfo: CREATE PROCEDURE [dbo].[sp_InsertStudentInfo] -- Add the param ...

  3. sqoop job从创建到执行

    在学习sqoop job之前,最好先学习一下sqoop命令的导入导出 sqoop 使用 import 将 mysql 中数据导入到 hive sqoop 使用 import 将 mysql 中数据导入 ...

  4. HDU 4714 Tree2cycle:贪心

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4714 题意: 给你一棵树,添加和删除一条边的代价都是1.问你将这棵树变成一个环的最小代价. 题解: 贪 ...

  5. 仿联想商城laravel实战---1、仿联想商城需求和数据库设计(lavarel如何搭建项目)

    仿联想商城laravel实战---1.仿联想商城需求和数据库设计(lavarel如何搭建项目) 一.总结 一句话总结: composer引入lavarel.配置域名.配置apache 1.项目名 le ...

  6. 分享知识-快乐自己:HTTP 响应码

    状态码 含义 100 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必须在 ...

  7. 分享知识-快乐自己:虚拟机 NET 网络配置

    第一步: 第二步: 第三步:   第四步:   第五步: 第六步: 第七步: 第九步: 第十步: 第十一步: 第十二步:   第十三步: 成功. 第十四步:开启开机自启动网路连接 cd /etc/sy ...

  8. 一 Django框架介绍——用pycharm创建Django项目

    Django框架介绍 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的软件设计模式,即模型M,视图V和控制器C.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内 ...

  9. JAVA堆内存和栈内存初步了解

    一.堆内存和栈内存 程序运行时内存分配有三种:静态存储分配,栈式存储分配,堆式存储分配 1.静态存储分配: 在程序编译时就可以确定数据目标在运行时所需要的内存,因此在编译时就为其分配固定大小的内存. ...

  10. Ubuntu 下安装mysql

    本文引用自 https://www.cnblogs.com/jpfss/p/7944622.html 此篇为http://www.cnblogs.com/EasonJim/p/7139275.html ...