推广

以实战 iOS 连续崩溃检测与自修复

iseeyu2年前 (2024-02-21)推广126

image.png

从方法名称 [UMCrash initUMCrash:channel:] 和 [WPKSetup sendAllReports] 可以很容易看出来, 这是友盟在做初始化的时候,对崩溃信息进行了一次检测,然后做上报,在处理数据的时候挂掉了。 看不到具体代码,控制台看到直接原因是: [NSTaggedPointerString objectForKey:]: unrecognized selector sent to instance 由于友盟的初始化发生在很早的时候(我们一般都放在启动阶段)。这就导致大多服务还没起来,应用就已经崩溃了。只要出现了这种情况,每次打开App, 都会因为一样的题,而连续闪退。 连续崩溃的后果 那么像这样的连续崩溃,会造成什么后果呢? 可以总结为以下的 3 点:

  • 开发无感知.由于在启动阶段就直接崩溃掉,崩溃收集平台 bugly / 友盟 都没有相关信息。更无从谈修复。

  • 用户无法反馈.因为每次进来都崩溃,也无法反馈相关信息给到客服。

  • 新用户 0 体验 .当 App 连续 3 次都进入就闪退,我自己来说,是肯定不再使用这一款无法体验的 App。

解决方案 面对上述的情况,因为掌握可复现的场景,通过技术手段,我们的确可以 hook 掉它的上传方法,从而解决崩溃问题。 例如这次,对我们发生的路径中的 [WPKSetup sendAllReports] 进行截获,不再执行。那么它当然不再崩溃。 但是上面解决方法有 3 点问题:

  • 成本取舍问题,原有的功能因为一次偶现崩溃场景而直接禁用。

  • SDK 功能缺失,甚至也可能引入新的问题。

  • 只解决了当下的场景,缺乏必要手段解决其它的连续崩溃问题。也就是说,保得了一时,保不了一世。

进行连续崩溃检测 在前面有提到过,连续崩溃的一大问题是–开发无感知。 也就是说,我们连问题发生了都不知道,所以首要做到的是发现问题。 通常最先想到的思路,就是和崩溃上报框架一样,通过捕获异常,来观察它的每次崩溃。 捕获异常的操作,也存在两个缺点:

  • 会与已有处理异常的代码重复,耦合

  • 与第三方 crash 收集框架的冲突,导致漏检测

对于第二点与第三方崩溃收集框架的冲突,是影响最大的地方,因为他们的代码通常对我们来说都是看不到的。

  • 持久化一个 crashCount 变量

  • 每次启动 crashCount = crashCount +1

  • 在 x 秒后,crashCount = 0

通过 crashCount 来代表崩溃次数,每次启动的时候让它加 1,如果 App 存活过一段时间,那么证明没有发生连续崩溃,将它置空复位。一旦超过我们设定的次数阈值,证明连续这几次时间阈值内,都没存活过去,发生了异常崩溃。 当然也存在误报的情况,比如用户在这段时间阈值内,主动杀掉 App。这一点通过调整次数和时间两方面的阈值,可以控制。 控制误报 我们可以在原来的方案中,更进一步控制误报,想办法监听用户主动杀App的场景:

  • 用户在前台杀APP

  • 用户在后台杀APP

对于误报的情况,大多数都是第一种,在几秒之内,启动时前台杀APP,iOS 中通过 UIApplicationWillTerminateNotification 来监听,收到通知后,将次数置空清零。 自动修复连续崩溃 要对于崩溃进行修复,首先需要知道这类问题的常见原因。 对于代码 bug 的问题,如果固定进入就必现崩溃的话,在测试流程就一般还是会暴露出来。当然并不完全排除代码崩溃的情况。 清除数据 造成线上问题连续崩溃的,肯定是一个“变量”,那么应该是:

  • 数据库

  • 存储文件

  • 服务端数据

对于 数据库 和 存储文件 的修复,我们都做一个清理操作,以本地数据的清理,来保证 App 的正常流程。 对于重要的数据定义,可以先传入云端存起来。 这次我们出现的友盟崩溃,也正是因为读取了存在本地的问题数据而导致连续闪退的。 重新请求/运行热修复包 而对于服务端数据处理的失败,通过与服务端排查,返回正常的数据进行解决。也可以提供入口让用户上报或者直接与我们联系。 甚至考虑引入动态修复手段,解决代码 bug ,请求以及运行热修复包。 具体处理 按照 微信读书团队的处理,是在 didFinishLaunching 的阶段做 hook。当触发崩溃限制数量后,进入修复,修复完成后再调用原方法 didFinishLaunching ,来按照原来的流程进入到 App. 结合我们的工程实际情况,自动修复流程与有细节差异:

  • Appdelegate 的 initialize 就开始有日志初始化。

  • 在 willFinishLaunching 的阶段,有一些数据和服务的初始化。

  • applicationDidBecomeActive 也有逻辑。

  • 进入首页需要拉取的请求和模块逻辑复杂。 需要解决这些问题,不止是对 didFinishLaunching 的阶段做 hook,还要分别对上述的情况进行处理,在崩溃数超过限制后进行拦截。 而中间整合,也发生了如服务找不到崩溃的问题等,需要一点点解决和整合。 目前临时增加一个方法:

+ (BOOL)needFixCrashes{    NSInteger launchCrashes = [self crashCount];        if (launchCrashes >= kContinuousCrashOnLaunchNeedToReport) {        return YES;    }    return NO;}

通过 needFixCrashes 来在各处做控制:


if(needFixCrashes){   return;}//原有正常逻辑处理

在修复后,我们再分别调用对应流程。相当于 [A do],[B do]..一个个去调用。 更好的思路

ps;作为iOS开发人员必看ios资料大全,其中你有想象不到的面试题和学习资料等等

其实对于上述流程,还有一个更好的做法,限于业务时间没做。

我们可以将流程中要 hook 的对象和方法,都想办法存储起来,如使用 NSMapTable 等。

在结束修复后,再按顺序遍历出来对象和方法一个个调用,走完一套启动的流程。

这里的好处在于复用,可以直接 addObject:Selector: 的方式就增加进去,之后修复完成,不需要再写 hard code 一个个调用。 3.3 最终流程

最终检测流程为:

  1. 启动App, crash=crash+1

  2. 检查 crash<maxCrash

  3. crash < maxCrash,则进入正常启动流程, 一段时间后就置空

  4. crash >= maxCrash, 进入修复引导

修复的流程设计为:

  1. 设置根控制器为新的控制器,并弹出修复框,提示“检测到应用可能已损坏,是否尝试修复?”

  2. 用户选择”取消”,则上报信息到平台,然后 App 退出到后台

  3. 用户选择”修复”,则进行我们的数据清理操作(重要数据考虑先云备份),然后上报信息。

  4. 修复完成后,直接重新初始化全部服务,进入首页。

  5. 最坏的情况,数据清理也仍然无济于事,记录下一段时间内的“修复”次数。提供方式直接联系到平台,在条件的情况下解决闪退。

实际操作当中,有不少业务待我们梳理,光做到在所有服务之前检测,如果之前没有专门的类收拢处理,就要花时间来做,或者在各处进行判断。总的来说,最主要的思路是:

  • 崩溃检测要在整个 App 里,做到最先启动。代码足够干净和简单。

  • 修复时的数据要分类,哪些重要的要备份,哪些直接删除。

  • 修复后进入 App,路径要足够完整,做到顺畅进入。

4. 总结


连续崩溃问题的发生,可以说是一个 App 最严重的问题,一般来说并不会出现。

而随着用户的增多,任何问题也有可能被无限放大。

所以作为技术人员,需要做好兜底的策略,尽量来消除此类问题,保证好用户体验,通过技术保护手段多留住一个用户就是一个用户。

何况事实证明,未雨绸缪是应该的,这次连续崩溃问题不就发生在了自己身上了吗?

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/56700.html

相关文章

SEO优化怎样提高网站的权重。

SEO优化怎样提高网站的权重。

现在很多的企业发展离不开线上营销,做网络SEO优化想要能够获取好的网站排名,这其中还得注重一些重要的SEO优化细节,做好站内各个细节优化才可以保证网站能够在搜索引擎中获得首页排名,那么SEO优化怎样提高网站的权重? 1、静态化网页 静态化的网页和动态化的相比,静态页面可以更方便...

营销管理(第16版)Marketing Management 读书笔 …

营销管理(第16版)Marketing Management 读书笔 …

洞察|净推荐值和顾客满意度1. 顾客对公司的价值部分取决于他们是否有能力和可能进行推荐,并参与正面的口碑传播。与从消费者那里获得正面口碑一样有用的是,可以让消费者直接融入公司,为建设的营销活动提供反馈和建议,进一步引导顾客忠诚度及提升销售额。贝恩公司( Bain )的弗雷德...

产品推广的几个阶段(3个阶段的3个方法让你领先一步)

产品推广的几个阶段(3个阶段的3个方法让你领先一步)

当企业开始做产品的时候,要想让产品得到更好的推广,就必须要了解产品到底是什么?如何推广?该怎么推广呢?今天给大家分享一下企业在产品研发阶段的推广方式。 一、产品定位 产品定位,简单的说就是对产品进行定位,明确了你需要做什么,你为什么需要的理由。产品定位的核心是一个公司定位自身产品的原因...

淘宝开服装店怎么找货源(开服装网店如何找货源)

淘宝开服装店怎么找货源(开服装网店如何找货源)

首先可以去加盟一些知名品牌,这样更容易扩张市场,其次,可以去阿里巴巴找货源,也可以去线下工厂做实地考察寻找好的货源,还可以去各地的批发市场寻找货源。...

优选十个SEO必备网站排名优化推广网站。

优选十个SEO必备网站排名优化推广网站。

做seo经常需要一些网站优化工具的辅助,比如网站关键词排名优化、外链发布平台和网站收录查询等各类工具,以便节省时间,让SEO变得更加轻松。那么,常用的SEO工具都有哪些呢?SEO优化中心精选了十款网站优化推广工具网站,希望对大家的SEO工作有所帮助。 1.爱站爱站网站长工具提供网站收录查询和站长...

快手信息流广告投放方法!

快手信息流广告投放方法!

  作为短视频平台的巨头之一,快手日活跃用户在今年1月份就突破了2.5亿,现在怕是已经… 快手信息流广告诞生于2017年3月,经过这两年零6个月的发展,已经比较完善和成熟了。 收到往期小伙伴的留言希望可以把信息流渠道单独进行讲解,今天我们就来说说快手信息流广告吧! 快手信...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片