> For the complete documentation index, see [llms.txt](https://awesome-tips.gitbook.io/ios/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://awesome-tips.gitbook.io/ios/you-hua/content-2.md).

# 3. 两种 App 启动连续闪退检测策略

**作者**: [KANGZUBIN](https://weibo.com/kangzubin)

当我们要做 App 日志上报时，需要考虑到一种行为：App 在启动时就崩溃闪退了，而且当遇到连续启动闪退（也就是每次打开 App 必崩）时，那几乎是灾难，但更可怕是，如果没有有效的监测手段，我们可能对已发生的这种线上严重问题毫不知情。

WeRead 团队博客的[《iOS 启动连续闪退保护方案》](http://wereadteam.github.io/2016/05/23/GYBootingProtection/) 和 MrPeak 老师的[《iOS App 连续闪退时如何上报 crash 日志》](http://mrpeak.cn/blog/ios-instacrash-reporting/) 分别介绍了两种简易的如何检测连续闪退的策略，在这里跟大家分享一下。

## 计时器方法

1）App 本地缓存维护一个计数变量，用于表示连续闪退的次数；

2）在启动入口方法 `application:didFinishLaunchingWithOptions:` 里判断 App 之前是否发生过连续闪退，如果有，则启动保护流程，自我修复，日志上报等，否则正常启动。判断的逻辑如下：

3）先取出缓存中的启动闪退计数 crashCount，然后把 crashCount 加 1 并保存；

4）接着使用 `dispatch_after` 方法在 5s 后清零计数，如果 App 活不过 5 秒计数就不会被清零，下次启动就可以读取到；

5）如果发现计数变量 > maxCount，表明 App 连续 maxCount 次连续闪退，启动保护流程，重置计数。

具体的代码如下图所示：

![7](/files/-LUYjjLAVYtkcqzFdJnJ)

这种计数器方法逻辑简单，与原有的代码耦合小。但存在误报可能（用户在启动 App 后又立即 kill 掉，会被误认为是 crash），不过可以通过设置时间阈值或者在 `applicationWillTerminate:` 里标记 App 是被手动 kill 来减少误报。

## 时间数组比对

我们可以在本地保存一个 App 每次启动时间、闪退时间、手动关闭时间的时间数组，然后在 App 启动时根据分析各个时间戳判断是否存在连续闪退（当闪退时间减去启动时间小于阈值 5 秒时，则认为是启动闪退），具体如下：

1）App 每次启动时，记录当前时间 launchTs，写入时间数组；

2）App 每次启动时，通过 crash 采集库，获取上次 crash report 的时间戳 crashTs，写入时间数组；

3）App 在接收到 `UIApplicationWillTerminateNotification` 通知时，记录当前时间戳 terminateTs，写入时间数组。注意，之所以要记录 terminateTs，是为了排除一种特殊情况，即用户启动 App 之后立即手动 kill app。

如果我们正确记录了上面三个时间戳，那么我们可以得到一个与 App crash 行为相关的时间线，如下图：

![8](/files/-LUYjjLCuBdlM8HBQBFK)

根据各种时间线的行为特征，我们只需要加上时间间隔判断，就能得知是否为连续两次闪退了。注意，如果两个 `crashTs` 之间如果存在 `terminateTs`，则不能被认为是连续闪退。

以上，介绍了两种检测 App 是否存在启动连续闪退的策略。

此外，对于连续闪退的保护方案以及连续闪退如何上报日志，请详细阅读开头提到的两篇博文。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://awesome-tips.gitbook.io/ios/you-hua/content-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
