数据库闪退_解决APP连续闪退的方案
首先要检测用户 App 出现了连续闪退的情况,有两种检测方法,捕获异常和计时器。
1. 捕获异常
检测连续闪退,可以通过捕获异常来实现,异常有以下种类:
Mach 异常:EXC_CRASH
UNIX 信号:SIGABRT
NSException 异常:应用层,通过 NSUncaughtExceptionHandler 捕获
在念茜的漫谈 iOS Crash 收集框架一文中详细介绍了 Mach 异常和 Unix 信号捕获 crash 的机制。简单来说,异常一般产生自 iOS 的微内核 Mach,然后在 BSD 层转换成 UNIX SIGABRT 信号,以标准 POSIX 信号的形式提供给用户。NSException 是使用者在处理 App 逻辑时,用编程的方法抛出。
如何捕获异常
通过以下方法捕获异常:
利用 Mach API 捕获 Mach 异常
通过 POSIX API 注册 signal(SIGSEGV,signalHandler) 来捕获 UNIX 异常信号
注册 NSUncaughtExceptionHandler 来捕获应用级异常
Crash 上报工具如 PLCrashReporter 通过注册 Mach 异常 + UNIX信号 的 handler 达到检测的目的,对用户提供了处理异常的接口。
如何检测
可以利用 PLCrashReporter 这类工具来检测连续闪退:
首先维护一个计数变量,表示连续闪退次数
在 PLCrashReporter 的 crash handler 中加入逻辑:如果启动 5s 内 crash 使计数器加一
每次启动时,如果连续闪退计数 > n,则检测到了连续闪退
启动后,执行一个定时任务,在 5s 后重置计数(如果 App 连续闪退则不会重置)
![](/assets/blank.gif)
流程图
优缺点
通过 Mach 异常、Unix 信号、NSException 异常来检测闪退,能获得更多的 crash 上下文,但由于 crash 收集框架多使用这些方法,可能会有这样的风险:与第三方 crash 收集框架冲突导致漏检测。另外,可能会与 App 已有的异常处理代码产生耦合。
2. 计时器方法
除了通过捕获异常的方式检测连续闪退,还可以通过计数器方法来检测:
维护一个计数变量,用于表示连续闪退的次数
在启动 application:didFinishLaunchingWithOptions: 后使计数加一
接着使用 dispatch_after 方法在 5s 后清零计数,如果 App 活不过 5 秒计数就不会被清零
如果发现计数变量 > n,表明 App 连续 n 次连续闪退,启动保护流程,重置计数。
当保护流程完成后,进入 App 正常启动流程
![](/assets/blank.gif)
流程图
优缺点
而计数器方法逻辑简单,与原有的代码耦合小。虽然有误报可能(在启动后立即被 kill 掉,误认为 crash),但是可以通过设置阈值来减小误报的误报率。
综上权衡,我们使用计时器方法检测连续闪退。
连续闪退修复
检测到连续闪退后,接下来要尝试对闪退进行修复,这里先分析可能的闪退原因,再结合微信读书的例子说明修复流程。
闪退原因
连续闪退,可能是 App 启动关键路径中执行了必 crash 的代码,原因可能有:
数据库损坏:在日常使用如异常退出、断电,或者错误的操作(参考:sqlite corruption causes)。
文件损坏:处理文件时如果没有@try...catch,损坏文件会抛出NSException导致 crash
网络返回数据处理异常:比如预期返回数组,但实际返回了字典,对字典对象执行-objectAtIndex方法会产生crash: unknow selector send to object;,或返回破损的 Tar 包,在解压失败导致 crash。
代码 bug:当必 crash 的代码出现在启动关键路径中,就会导致连续闪退。
针对 1,可以通过工具修复数据库,或者删除 DB。针对2,可以删除文件来进行修复。对于 3 和 4,我们需要具体地分析 crash 案例,通过 JSPatch 来进行修复。
微信读书的修复流程
为了应对上述导致连续闪退的原因,微信读书的修复流程为:
进入 didFinishLaunch 时检查是否有连续闪退,无则执行 5
弹 Toast 提示用户是否修复,轻触『修复』执行2,否则执行 5
尝试下载并执行 JSPatch 补丁
这里是为了解决上述第4点 - 代码 bug 导致的闪退,使用 JSPatch[github]可以进行热修复。在 didFinishLaunching 时,会卡住界面发请求检查是否有可用的 JSPatch 脚本,如果有则加载执行,解决代码 bug 导致的闪退。
尝试删除Documents/Library/Caches目录下的所有文件
这里直接删除了所有用户数据,适用于微信读书这种所有数据都在云端,删除后可以完全从云端恢复。如果你的 App 不属于这种场景,那么应该在 repairBlock 中自定义修复逻辑,比如:
a. 不删除文件,只修复数据库
b. 修复前把用户数据备份到云端
c. 收集 crash 样本,查明原因,定制 JSPatch 修复补丁并下发
退出微信读书登录状态
进入原 didFinishLaunch
连续闪退检测 + 保护流程如图所示:
![](/assets/blank.gif)
实现
检测和连续 crash 并修复需要修改原-application:didFinishLaunchingWithOptions:逻辑,有几种方法:
直接修改-application:didFinishLaunchingWithOptions:方法。
新建一个SubAppDelegate类来继承AppDelegate,覆盖-application:didFinishLaunchingWithOptions:方法,然后把main()函数中的AppDelegate替换为SubAppDelegate
新建一个AppDelegate扩展,然后用 method swizzle 的方法替换-application:didFinishLaunchingWithOptions:方法。
上述三种方案,对现有项目改动代价是 1 > 2 > 3。因此,我们使用对源码修改代价最小的方案 3 来替换-application:didFinishLaunchingWithOptions:。
检测的逻辑 GYBootingProtection 已经处理好,修复的处理预留了接口,可以由用户自定义,把自定义的修复流程传入 repairBlock 即可。
使用
引入项目
下载(github)源码 ,将src目录下所有文件拖拽到你的 Xcode 项目
在AppDelegate+GYBootingProtection.m的onBeforeBootingProtection方法中添加检测前需要执行的代码,比如设置crash上报:
- (void)onBeforeBootingProtection {
[GYBootingProtection setLogger:^(NSString*msg) {
// setup logger
NSLog(@"%@", msg);
}];
[GYBootingProtection setReportBlock:^(NSIntegercrashCounts) {
// setup crash report
}];
}
在onBootingProtection方法中添加修复逻辑,比如删除文件:
- (void)onBootingProtection {
// 检查 JSPatch 更新
...
// 删除 Documents Library Caches 目录下所有文件
[GYBootingProtection deleteAllFilesUnderDocumentsLibraryCaches];
...}
如需执行异步的修复逻辑,在onBootingProtectionWithCompletion:方法添加修复逻辑,并在完成修复后调用 completion :
- (void)onBootingProtectionWithCompletion:(BoolCompletionBlock)completion {
[selfonBootingProtection];
// 异步修复
[selfasyncRepairWithCompletion:^(void) {
// 正常启动流程
if(completion) completion();
}];
}
测试
首先制造连续闪退场景:
启动后 5 秒内,双击 Home 通过上划手势 kill 掉 App,重复多次。(也可以在代码里人为制造crash)
当连续闪退超过 5 次时,会提示用户修复:
![](/assets/blank.gif)
用户轻触修复,App 重置初始状态,连续闪退问题解决!
数据库闪退_解决APP连续闪退的方案相关推荐
- android 签名包闪退,解决APP连续闪退的方案,你还不知道的签名方式
原标题:解决APP连续闪退的方案,你还不知道的签名方式 用户在使用APP检测到连续闪退后,接下来要尝试对闪退进行修复,这里先分析可能的闪退原因: 闪退原因 连续闪退,可能是 App 启动关键路径中执行 ...
- apk闪退_解决安卓手机闪退的通用办法!
原标题:解决安卓手机闪退的通用办法! 丫丫网资讯,很多安卓用户都会反应手机在使用过程中会出现手机闪退问题,今天这个问题也许可以解决了.一起来瞅瞅吧! 1.安卓手机由于其系统特性原因,在手机缓存过多的情 ...
- 苹果上传闪退 php,苹果手机app频繁闪退原因以及解决方法
就算再流畅的ios系统,再好的iPhone手机,用久了都会遇到一个这样子的问题,就是闪退的问题,而且APP闪退占据多数.那该怎么修复呢?闪电修告诉你原因和搞定的步骤. 闪电修上门维修手机 我们先了解下 ...
- autocad2014 第二次打开闪退_解决win10下autocad2014闪退的修复方法
Win10下AutoCAD 2014打开出现闪退怎么解决?有用户反映经过一次系统更新后,发现AutoCAD 2014打开会出现闪退的情况.下面和大家分享一下Win10下AutoCAD 2014打开出现 ...
- 程序闪退_苹果APP日常使用时一直闪退怎么办?
ios用户在日常使用应用一定碰到过点进APP后就出现闪退的现象,有的应用甚至无限闪退无法打开.有用户反映,之前的王者荣耀就出现了在新升级的ios14 beta4版本的系统中出现无限闪退的情况.闪退就是 ...
- arduino win10闪退_解决Win10天气应用闪退的两种方法
Windows系统中都自带天气应用,但是安装了Win10系统后,就发现,打开天气应用出现闪退的情况,其他应用都正常,这要怎么解决呢?下面小编告诉大家解决Win10天气应用闪退的两种方法. 方法一 1. ...
- java在win8闪退_解决Win8/Win8.1系统下的IE11闪退的六种方法
相较于IE10浏览器以前的版本,IE11有了很较大的提升.界面呈扁平化的风格,浏览网页时给人一种很清新的感觉.不过有部分使用win8或者win8.1操作系统的用户却有遇到安装的IE11会有闪退的困扰, ...
- apk闪退_安卓手机经常闪退怎么办?安卓手机闪退解决办法
平时我们在使用手机的时候可能会发现,安卓手机使用的时间长一点就可能会出现手机闪退的现象,那么如何来解决手机闪退的问题呢?今天,刷机帮小编就为大家分享一篇如何解决手机闪退问题的教程,大家可以根据自己的实 ...
- ios python3闪退_解决Python3 cx_Freeze打包闪退/无法执行以及No module named 'matplotlib.backends.backend_tkagg'...
[虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是可能存在.所以了解原理很重要.这里讲述在没有ARC的情况下,如何使用Instruments来查找程 cx_Free ...
- 怎么解决java.exe闪退_解决Eclipse闪退问题的方法总结
1.在C:/WINDOWS/system32 系统文件夹中ctrl+F 然后搜索java.exe,如果存在java.exe, javaw.exe etc.全部删除. 2.内存不足,打开Eclipse目 ...
最新文章
- ceph部署出现错误及解决
- rdd数据存内存 数据量_spark系列:spark core 数据交互技术点(数据模型)
- Maximum XOR Sum 系列问题
- 远程连接Oracle 数据库连接报错ORA-12638身份检索失败
- canvas1:简单介绍、开始使用、画直线+虚线
- 京东发布全球物流无人机研报:美国领先、非洲政策最开放,中国产业链全景最复杂...
- Linux技术进阶示意图
- NIOS II EDS NIOS II IDE 转载
- 使用ExtJS创建前端WebQQ界面
- php 网站实例,php网站实例【货币问答】- php网站实例所有答案 - 联合货币
- Elasticsearch(036):es中批量操作之mget(批量查询)
- WINDOWS 7 X64专业版SP1后续补丁包20150901(微软官方下载地址列表)
- 从电影《心灵捕手》谈起
- 【Android TV】 遥控器Enter键无法调出软键盘
- NFC(Near Field Communication,近场通信)相关
- tryhackme--Overpass 2 - Hacked
- php函数名命名规范,PHP语言的命名规则
- CF #768 E.Flipping Ring
- 简要概述服装设计管理
- Linux 设备分配清单(kernel:2.6+)