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"
            }
        }

解法二:使用真机

  • 问题四

dyld[51346]: 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 版本

相关推荐
拭心9 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
fantasy_arch9 小时前
CPU性能优化-磁盘空间和解析时间
网络·性能优化
带电的小王11 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡11 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道12 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
码农老起12 小时前
企业如何通过TDSQL实现高效数据库迁移与性能优化
数据库·性能优化
java_heartLake12 小时前
Vue3之性能优化
javascript·vue.js·性能优化
arnold6612 小时前
探索 ElasticSearch:性能优化之道
大数据·elasticsearch·性能优化
阿甘知识库13 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道13 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频