Android 开发高手课 01 | 崩溃优化(上)关于“崩溃”那些事儿

本文微信公众号「安卓小煜」首发

1. 背景

最近重读了 Android 开发高手课,记录一下阅读的一些笔记。

包括有些之前课后作业完成不了的,这次也都一并完成了。

如果想看课后作业的,可以直接定位到最后一节,前面的都是原文的一个汇总。

2. 崩溃的分类

  1. Java 崩溃:在 Java 代码中,出现了未捕获的异常,导致程序异常退出。
  2. Native 崩溃:一般都是因为在 Native 代码中访问非法地址,也可能是地址对齐出现了问题,或者发生了程序主动 abort,这些都会产生相应的 signal 信号,导致程序异常退出。

2.1 Native 崩溃的捕获流程

  • 编译端。编译 C/C++ 代码时,需要将带符号信息的文件保留下来。
  • 客户端。捕获到崩溃时候,将收集到尽可能多的有用信息写入日志文件,然后选择合适的时机上传到服务器。
  • 服务端。读取客户端上报的日志文件,寻找合适的符号文件,生成可读的 C/C++ 调用栈。

2.2 Native 崩溃捕获的难点

最核心的是怎么样保证客户端在各种极端情况下依然可以生成崩溃日志

  • 情况一:文件句柄泄漏,导致创建日志文件失败,怎么办?
    提前申请文件句柄 fd 预留,防止出现这种情况
  • 情况二:因为栈溢出了,导致日志生成失败,怎么办?
    使用常见的 signalstack,预留部分堆空间
  • 情况三:整个堆的内存都耗尽了,导致日志生成失败,怎么办?
    Breadpad 做法是重新封装了 Linux Syscall Support,来避免直接调用 libc。
  • 情况四:堆破坏或二次崩溃导致日志生成失败,怎么办?
    从原进程 fork 出子进程。某些特殊情况下,还可能从子进程 fork 出孙进程。

2.3 选择合适的崩溃服务

对于很多中小型公司来说,可以选择一些第三方的服务。

从产品化和社区维护来说,推荐 Bugly。

从技术深度跟捕获能力来说,推荐啄木鸟平台。

3. 一些衡量指标

3.1 如何客观地衡量崩溃

如果想评估崩溃造成的用户影响范围,我们会先去看 UV 崩溃率。

UV 崩溃率 = 发生崩溃的 UV / 登录 UV

3.2 如何客观地衡量稳定性

  • 怎么去发现应用中的 ANR 异常呢?

    1. 使用 FileObserver 监听 /data/anr/traces.txt 的变化
    2. 监控消息队列的运行时间

    这两个方法都无法准确的发现 ANR

  • UV 异常率 = 发生异常退出或崩溃的 UV / 登录 UV

4. 课后作业

机器环境

OS version: macOS Monterey 12.5

AS version: Android Studio Electric Eel | 2022.1.1 Patch 2

仓库地址:Chapter01

重点说一下在按照 README 操作的过程中遇到的问题。

  • 问题一

NDK is missing a "platforms" directory.

If you are using NDK, verify the ndk.dir is set to a valid NDK directory. It is currently set to /Users/zhanzengyu/Library/Android/sdk/ndk-bundle.

If you are not using NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties to remove this warning.

解法一(推荐):配置 NDK 版本,这边使用 16.1.4479499 是可以的

解法二:在 ndk-bundle 下面创建 platforms 空目录

  • 问题二

ABIs arm64-v8a are not supported for platform. Supported ABIs are armeabi-v7a, x86.

解法一(推荐):配置 NDK 版本,这边使用 16.1.4479499 是可以的

解法二:删除 breakpad-build 和 sample 下 abiFilters 里面的 "arm64-v8a"

  • 问题三

x86 模拟器点击 crash 按钮确实闪退了,但是没有生成 dmp 文件

解法一:按照 GitHub 说的方式配置(PS:注意,如果 NDK 版本不对,会报错:GCC is no longer supported)

  1. 将 ndk 切换到 16b,下载地址: github.com/android/ndk...
  2. 在 Androidstudio 里设置 ndk 路径为ndk-16b的路径
  3. 在 sample 和 breakpad-build 的 build.gradle 配置里增加如下配置
javascript 复制代码
 externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
                arguments "-DANDROID_TOOLCHAIN=gcc"
            }
        }

解法二:使用真机

  • 问题四

dyld51346: Symbol not found: (__ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE)

Referenced from: '/Users/zhanzengyu/Desktop/zengyu/project/github/Chapter01/tools/mac/minidump_stackwalk'

Expected in: '/usr/lib/libstdc++.6.dylib'

1 51346 abort ./098877a7-142f-4668-8784c3b0-fc8eaaef.dmp > crashLog.txt

解决方案:使用 AndroidStudio 里面自带的 minidump_stackwalk

位置在:/Applications/Android\ Studio.app/Contents/plugins/android-ndk/resources/lldb/bin/minidump_stackwalk

总结来说,最重要的是要配置正确的 NDK 版本

相关推荐
GitLqr11 小时前
Flutter 3.44 插件内置 Kotlin (KGP) 双向兼容适配指南
android·flutter·dart
随遇丿而安16 小时前
第11周:Activity 跳转与传值 + 跳转优化
android
私人珍藏库17 小时前
[Android] BBLL 开源第三方B哩电视TV端
android·app·生活·工具·多功能
云栖梦泽在18 小时前
Claude Code / Codex 使用卡顿怎么办?AI 编程 Agent 连接失败与网络排查思路
网络·人工智能·网络协议·chatgpt·性能优化
杉氧19 小时前
跨平台资源管理:一套代码如何搞定 Android、iOS 和 Web 的图片与多语言?
android·架构·android jetpack
爱喝水的鱼丶19 小时前
SAP-ABAP:接口 vs 抽象类:ABAP OOP两类扩展方式的差异与选型原则
运维·性能优化·sap·abap·erp·经验交流
安卓修改大师20 小时前
安卓修改大师实战:从反编译到定制的完整APK修改指南
android
柚鸥ASO优化21 小时前
安卓APP推广的“降本增效”密码:守好商店内,打好商店外
android·aso优化
我是一颗柠檬1 天前
【Java项目技术亮点】EXPLAIN深度分析与慢查询治理
android·java·开发语言
Android-Flutter1 天前
android compose shadow 阴影 使用
android·kotlin·compose