当前位置: 首页 > news >正文

Android---App 崩溃

崩溃问题是衡量 App 质量的决定性考核标准。Android 系统会输出各种相应的 log 日志,很大程度上降低了工程师 debug 崩溃问题的难度。如果要给 crash 日志进行分类,可以分为2大类:JVM 异常(Exception)堆栈信息native 代码崩溃日志

JVM 异常堆栈信息

Java 中异常(Exception)分两种:检查异常(checked Exception)和非检查异常(unchecked Exception)

\bullet 检查异常是在代码编译时期,Android Studio 就会提示代码有错误,无法通过编译。比如 IOException。如果没有在代码中将这些异常 catch,而是直接抛出,最终也有可能导致程序崩溃。

\bullet 非检查异常包括 error 和运行时异常(RuntimeException)。AS 并不会在编译时期提示这些异常信息,而是在程序运行时期因为代码错误而直接导致程序崩溃。比如 OOM 或者空指针异常(NPE)

Java 异常

对于上述两种异常,我们都可以使用 UncaughtExceptionHandler 来进行捕获操作。它是 Thread 的一个内部接口,定义如下

对于传入的 Thread,如果因为未捕获异常而导致被终止,uncaughtException 则会被调用。我们可以通过它来间接捕获程序异常,并进行异常信息的记录工作,或者给出更友好的异常提示信息。 

自定义异常处理类

自定义类实现 UncaughtExceptionHandler 接口,并实现 uncaughtException() 方法。如下代码所示

需要注意的几点,自定义异常处理类中,需要持有线程默认异常处理类,如图中红框处所示。这样做的目的是在自定义异常处理类无法处理或者处理异常失败时,还可以将异常交给系统做默认处理。如果自定义异常处理类成功处理异常,需要进行页面跳转或者将程序进程杀死,否则程序会一直卡死在崩溃界面,并弹出无响应对话框。在上面代码中通过 CrashDisplayActivity 页面来展示所捕获的异常详细信息。

一般情况下,在 handleException() 方法中需要做以下几件事情:

1)收集 crash 的现场相关信息。如下面方法获取当前 App 的版本信息,以及所有手机设备的相关信息

2)日志的记录工作,将收集到的信息保存在本地。比如以文件的方式保存。从下图中可以看出,除了我们自己收集的日志,还需要将系统抛出的异常信息也保持到文件中,方便后续开发人员分析问题原因。

使用自定义异常处理类

上面我们提到的 LagouExceptionHandler 自定义异常处理类定义好之后,就可以将其初始化。并将主线程注册到 LagouExceptionHandler 中。如下

最终,报错的 crash 日志信息格式如下图所示

需要注意的是,因为使用了文件写操作,所以需要动态申请文件操作的权限。

native 异常

当程序中的 native 代码发生崩溃时,系统会在 /data/tombstones/ 目录下保存一份详细的崩溃日志信息。如果一个 native crash 是必现的,不妨在模拟器上重现 bug。并将 /data/tombstones 中的崩溃日志拉到本地电脑中加以分析。

比如,创建一个模拟 native crash 的项目 LagouNativeCrash。项目结构如下

MainActivity 中有一个点击按钮 Button,当点击此按钮时,会调用 crash() 方法触发 native 代码崩溃。

native crash 在 native-lib.cpp 文件中声明,如下

当点击 Button 触发 native 崩溃之后,系统会在 /data/tombstones 目录下生成 tombstones 日志文件。可以在此日志文件中查看详细的保存信息。如下所示

但是,如果 native crash 是偶发现象,并且在模拟器上一时难以复现。那么就需要将工作交给测试工程师,在真机上尝试复现。

这种情况下就需要一种机制,将 native crash 现场的日志信息保存到可以访问的手机目录中。目前比较成熟,使用也比较广泛的是谷歌的 Breakpad。Breadpad 是一个跨平台的开源库,也可以在其 Breakpad Github 上下载自己编译,并通过 JNI 的方式引入到项目中。

NDK 导入 Breakpad

在 Breakpad GitHub 官网上,有一个 README Android 的介绍文件,这个文件专门介绍了如何在 Android 项目中导入 Breakpad。我们可以直接使用 cmake 方式将其编译为一个静态库。

在捕获 native crash 之前,需要初始化 Breakpad。主要是设置 Breakpad 保存 crash 日志的路径,如下所示

图中传入的 path 就是 Breakpad 保存日志的文件目录,一般情况下保存在外置 SDK 目录。

初始化好之后,就可以在我们自己的 native 业务层模拟一个崩溃现场。Breakpad 会自动捕获这次 crash,并将生成的 crash 信息保存在所设置的目录中。

breadpad 生成的文件是 .dmp 文件,需要将其进行转换,如下所示

线上崩溃日志捕获

上面介绍了 java 和 native 崩溃的捕获都是基于现场能够复现 bug 的前提。但是,对于线上用户,这种操作方式是不太现实的。首先,不可能将一个 debug 版本的 APK 安装到终端用户的手机上;其次,不太可能要求用户操作一遍手机并将某一目录下的文件发送给开发人员。

对于大多数公式来说,针对线上版本没有必要自己实现一个抓取 log 的平台系统。最快速的实现方式就是集成第三方 SDK。目前比较成熟,采用也比较多的就是腾讯的 Bugly。Bugly 能够满足线上版本捕获 crash 的所有需求,包括 java 层和 native 层的 crash 都可以获取相应的日志。并且每天 Bugly 都会邮件通知上一天的崩溃日志,方便测试和开发统计 bug 的分布以及崩溃率。

其它的 crash 上报工具,比如 XCrashSentry

这两者比 Bugly 好的地方就是除了自动拦截界面崩溃事件,还可以主动上报错误信息。以 XCrash 为例,基本使用如下所示

可以看出 XCrash 的使用更加灵活,工程师的掌控性更高。可以通过设置不同的过滤方式针对性的上报相应的 crash 日志。并且在捕获到 crash 之后可以加入自定义的操作,比如本地保存日志或者直接进行网络上传。

Sentry 还有一个好处就是可以通过设置过滤,来判断是否上报 crash 日志。这对于 SDK 的开发人员是很有用的,比如一些 SDK 的开发商只是想收集自身 SDK 引入的 crash,对于用户的其他操作导致的 crash 进行过滤。这种情况就可以考虑集成 Sentry。

总结

本次主要介绍了 Android 崩溃的相关知识。对于 Android 工程师来说,crash 可以分为2类:Java 层和 Native 层

\bullet Java 层一般通过自定义 UncaughtExceptionHandler 进行异常拦截

\bullet Native 层可以考虑集成谷歌的 breakpad 进行捕获,并保存日志在本地

最后介绍了几个线上捕获 crash 的工具:Bugly、XCrash 和 Sentry。

相关文章:

Android---App 崩溃

崩溃问题是衡量 App 质量的决定性考核标准。Android 系统会输出各种相应的 log 日志,很大程度上降低了工程师 debug 崩溃问题的难度。如果要给 crash 日志进行分类,可以分为2大类:JVM 异常(Exception)堆栈信息和 nativ…...

DocTemplateTool - 可根据模板生成word或pdf文件的工具

你是否经常遇到这样的场景:产品运营有着大量的报告需求,或者给客户领导展现每周的运营报告?这些文档类的任务可以交给运营同事,他们负责文档排版和样式,你作为开发人员你只需要提供数据源,和一个映射表&…...

Python+reuqests自动化接口测试

1.最近自己在摸索Pythonreuqests自动化接口测试,要实现某个功能,首先自己得有清晰的逻辑思路!这样效率才会很快! 思路--1.通过python读取Excel中的接口用例,2.通过python的函数调用,get/Post 进行测试&…...

【Java 进阶篇】保护你的应用:Java 过滤器实现敏感词汇过滤

在开发 Web 应用程序时,安全性是至关重要的一环。保护用户免受恶意内容的侵害是开发者义不容辞的责任之一。在这篇博客中,我们将深入研究如何使用 Java 过滤器来过滤敏感词汇,确保用户输入的内容不包含不良信息。我们将采用简单而实用的方法&…...

目标检测网络系列——YOLO V4

文章目录 目标检测技术总结两种优化方向Bag of freebiesBag of specialsYOLO4网络结构网络架构(architecture)的选择基础网络结构的选择网络"插件"的选择。BoF和BoS的选择(Selection of BoF and BoS)YOLO4的其他改进点对比实验不同的特征(数据增强方法)之间的对比det…...

如何在Linux上部署1Panel运维管理面板并远程访问内网进行操作

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器,包括主机监控、…...

CentOS系统安装vsftpd

下载并安装vsftpd apt-get install vsftpd 安装后检查 service vsftpd status 修改配置文件(被动/匿名用户模式) vi /etc/vsftpd.conf anonymous_enableNO listenYES listen_port21 ascii_upload_enableYES ascii_download_enableYES local_enableYES guest_enable…...

手握“发展密钥”,TCL科技或迎价值重估?

在高度竞争且快速变化的泛半导体产业,每一次周期性或结构性的变化,都会对企业经营策略带来深远的影响。 2023年前三季度,泛半导体产业迎来结构性复苏。其中,主流显示领域供需关系趋向健康化,半导体显示行业整体上量价…...

A star算法

1. 算法的理解 1.2 a 星算法的基本的原理 a 星 是一种启发式搜索算法, 用于在地图中的两个目标点之间寻找最短的路径,它结合了最优先搜索和Dijkstra算法的特点,通过考虑从起点到当前点的距离(或者代价 g(n) ) 和估算…...

node插件MongoDB(四)—— 库mongoose 操作文档使用(新增、删除、更新、查看文档)(二)

文章目录 前言(1)问题:安装的mongoose 库版本不应该过高导致的问题(2)重新安装低版本 一、插入文档1. 代码2. node终端效果3. 使用mongo.exe查询数据库的内容 二、删除文档1. 删除一条2. 批量删除3. 代码 三、修改文档…...

JavaFX入门和网格布局面板的使用,Dao层交互,舞台与场景切换以及其他控件的使用

网格布局 将整个面板划分为若干个格子 , 每个格子的大小是一样的 , 每个格子中可以放置一个控件(布局) , 类似于表格的方式。在网格布局 中放入控件的时候 , 还需要指定位置。 GridPane gridPane new GridPane(); 我们将要排出这个布局 , 也就是登陆页…...

数据中台之数据分析

效果界面 技术方案 Notebook集成 在您的数据平台上,创建一个能够与Jupyter Notebook通讯的服务。通过Jupyter Notebook的HTTP API与Notebook实例进行交互,执行代码、获取输出等。用户界面 在数据开发/数据分析的代码框右上方,添加一个机器人样式的图标,用户点击后可以调起…...

龙芯loongarch64服务器编译安装scipy

前言 根据我之前的文章介绍,龙芯loongarch64服务器中的很多python依赖包安装有问题,发现其中安装的"scikit-learn"就无法正常使用,所有这里在 pip3 install scikit-learn -U -i https://pypi.tuna.tsinghua.edu.cn/simple 的时候发现"scipy"就无法正常…...

ubuntu(18.04)中安装open babel docker镜像并在php项目中调用容器中的obabel命令解析结果使用

使用软件: obabel镜像:informaticsmatters/obabel docker:http:// https://www.docker.com/ 安装docker #卸载旧版本sudo apt-get remove docker docker-engine docker-ce docker.io#更新索引包sudo apt-get update#安装 apt 依赖包&…...

02-PostgreSQL的基本使用

一、数据库操作 ①: 登录到数据库 psql -U postgres -d postgres -h 127.0.0.1②:查看所有数据库 \l③: 创建数据库 # 创建一个名为 mydb 的数据库 create database mydb;④:切换数据库 # \c 数据库名 \c mydb⑤:删除数据库 # 删除前 先确保数据库没有被连接 drop databa…...

uniapp 实现路线规划

UniApp是一个跨平台的应用开发框架,可以帮助开发者快速地在多个平台上构建应用程序。其中,实现路线规划是一个常见的需求,特别是对于地图类应用或者出行类应用来说,路线规划功能是非常重要的。 首先引入QQMapWX; impo…...

C语言C位出道心法(五):内存管理

C语言C位出道心法(一):基础语法 C语言C位出道心法(二):结构体|结构体指针|链表 C语言C位出道心法(三):共用体|枚举 C语言C位出道心法(四):文件操作 C语言C位出道心法(五):内存管理 一:C语言内存管理认知 二:C语言中内存堆|栈认知 三:C语言中引用内存丢失认知...

Flink之SQL客户端与DDL操作

SQL客户端与DDL操作 Flink SQLSQL客户端1.启动Flink2.启动Flink的SQL客户端3.HELP命令4.验证连接5.结果显示模式6.执行配置 数据库操作1.创建数据库2.查询数据库3.修改数据库4.删除数据库 表操作1.创建表表列属性表Watermark属性列PRIMARY KEY属性列PARTITIONED BY属性列WITH选…...

记录第一次银行测试岗面试【总结几点面试不要犯得错误】

LZ在一个18线小城市做测试,近来想走出自己的舒适区,去做一点不一样的测试工作。 18线地区,测试工作并不多。最好的差不多就是LZ目前待着的公司了。遂决定去魔都闯荡几年,对一个在魔都无房无车无户口的人来讲,这意味着…...

一篇带你精通php

华子目录 什么是phpphp发展史平台支持和数据库支持网站静态网站和动态网站的区别静态网站动态网站的特点 关键名词解析服务器概念IP的概念域名DNS端口 web程序的访问流程静态网站访问流程动态网站访问流程 php标记脚本标记标准标记(常用) php注释 什么是…...

HTTrack跨平台实战手册:从环境配置到高级镜像的完整指南

HTTrack跨平台实战手册:从环境配置到高级镜像的完整指南 【免费下载链接】httrack HTTrack Website Copier, copy websites to your computer (Official repository) 项目地址: https://gitcode.com/gh_mirrors/ht/httrack HTTrack网站镜像工具是一款功能强大…...

别再死记硬背了!用Fluent做流体仿真,这5个核心参数设置对了才算入门

别再死记硬背了!用Fluent做流体仿真,这5个核心参数设置对了才算入门 刚接触Fluent的工程师和学生常常会陷入一个误区:试图记住所有理论模型和参数的细节。但真实工程场景中,80%的仿真问题往往源于20%的关键参数设置不当。本文将聚…...

保姆级教程:用STM32CubeIDE搞定STM32F407的USB虚拟串口(CDC)通信与速度测试

STM32F407 USB CDC通信实战:从零构建高速串口通道 引言 在嵌入式开发领域,可靠的数据传输始终是核心需求。传统UART串口受限于115200bps的速率天花板,而USB CDC(Communication Device Class)技术则为我们打开了高速通信…...

4月21日发布!OPPO Pad Mini 要给小平板正名了

4月21日19:00,OPPO将召开新品发布会,除了Find X9s Pro等旗舰手机,最让我期待的就是OPPO Pad Mini这款小平板。说实话,这几年我一直觉得小平板是“鸡肋”——手机屏幕越做越大,折叠屏又能兼顾大屏,8.8英寸的…...

多云环境测试:跨平台方案深度解析与实践指南

当多云战略遇见跨平台应用随着企业数字化转型进入深水区,业务形态正以前所未有的复杂度和广度展开。一方面,为追求弹性、成本优化与风险规避,多云架构已成为企业技术栈的必然选择,工作负载分布于AWS、Azure、阿里云乃至边缘节点之…...

手把手教你为华大HC32F460并口屏(ILI9341)配置emWin:直接访问与间接访问两种模式详解

华大HC32F460并口屏(ILI9341)的emWin驱动设计:直接访问与间接访问模式深度解析 在嵌入式GUI开发中,显示性能往往是决定用户体验的关键因素。当使用华大半导体HC32F460这类高性能MCU驱动320x240分辨率的ILI9341并口屏时,如何通过emWin图形库实…...

终极指南:3步快速部署MoneyPrinterPlus AI短视频自动生成工具

终极指南:3步快速部署MoneyPrinterPlus AI短视频自动生成工具 【免费下载链接】MoneyPrinterPlus AI一键批量生成各类短视频,自动批量混剪短视频,自动把视频发布到抖音,快手,小红书,视频号上,赚钱从来没有这么容易过! 支持本地语音模型chatTTS,fasterwhisper,GPTSoV…...

手把手教你用Qwen3-VL-8B:上传图片就能提问的AI助手搭建

手把手教你用Qwen3-VL-8B:上传图片就能提问的AI助手搭建 1. 为什么你需要这个AI助手 想象一下这样的场景:你正在整理手机里上千张照片,突然看到一张多年前的旅行照,却想不起来具体是在哪里拍的。或者你收到一张复杂的图表&#…...

Mac用户必备:12306ForMac抢票助手完整使用指南

Mac用户必备:12306ForMac抢票助手完整使用指南 【免费下载链接】12306ForMac An unofficial 12306 Client for Mac 项目地址: https://gitcode.com/gh_mirrors/12/12306ForMac 你是否曾为在Mac上抢购火车票而烦恼?传统网页版12306在高峰期经常卡顿…...

深度解析:如何用Lumafly高效管理空洞骑士模组的完整指南

深度解析:如何用Lumafly高效管理空洞骑士模组的完整指南 【免费下载链接】Lumafly A cross platform mod manager for Hollow Knight written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/lu/Lumafly Lumafly是一款专为《空洞骑士》设计的跨平台…...