文章目录
- bugreport
- 获取报告
- 设备
- 模拟器
- adb命令
- 用户
- 报告目录
- 阅读错误报告
- logcat
- 定义
- 日志记录
- 抓取日志
- 过滤优先级
- 输出格式
- 格式修饰符
- 日志缓冲区
- ANR
- 触发ANR
- 避免ANR
- 工作线程
- ANR日志
- 定位无响应应用
- 查看堆栈跟踪
- 死锁
- activity
- 内存
- 内存不足
- 内存快照
- 广播
- 显示器争用
- 后台编译
- 叙述
- 电源
- 程序包
- 进程
- 扫描
bugreport
获取报告
Android developers🔗
设备
1、启用开发者选项(连续点击设备版本号
2、点击bug报告(不同系统稍有差异
3、选择所需bug报告类型,点击报告
4、通知栏会有完成提示,点击可分享
5、文件管理中可找到报告文件
模拟器
“Extended controls”窗口中的 File a bug 功能:
1、点击模拟器面板中的 More 图标
2、在 Extended controls 窗口中选择 Bug report
此时系统会打开一个屏幕,您可以在其中查看 bug 报告详细信息,例如屏幕截图、AVD 配置信息和 bug 报告日志。您还可以输入一条包含重现步骤的消息,以便与报告一起保存。
3、等待 bug 报告完成收集,然后点击 Save Report
adb命令
adb bugreport 路径
用户
1、GooglePlay管理中心
2、build.gradle中添加Firebase崩溃报告功能
报告目录
生成的报告文件默认命名为bugreport-BUILD_ID-DATE.zip
bugreport-BUILD_ID-DATE.txt
就是 bug 报告,包含系统服务 (dumpsys)、错误日志 (dumpstate) 和系统消息日志 (logcat) 的诊断输出,系统消息包括设备抛出错误时的堆栈轨迹,以及从所有应用中使用 Log 类写入的消息。
阅读错误报告
Android source🔗
logcat
Android developer🔗
定义
logcat是一个命令行工具,用于转储系统消息日志,包括设备抛出错误时的堆栈轨迹,以及从所有应用中使用 Log 类写入的消息。
日志记录
系统进程logd
维护的一组结构化环形缓冲区,缓冲区是固定由系统定义的。类型包含如下:日志缓冲区
抓取日志
adb shell logcat
,可简写为adb logcat
adb logcat --help
查询可用选项
每行记录以timestamp PID TID log-level
开头
过滤优先级
以下优先级由低到高:
- V-Verbose:详细
- D-Debug:调试
- I-Info:信息
- W-Warn:警告
- E-Error:错误
- F-Fatal:严重错误
- S:静默(不输出任何内容)
输出格式
修改日志的输出格式,以显示特定的数据字段
格式修饰符
adb logcat -v --help
- brief,显示优先级/标记、PID
- long,显示所有元数据字段,空行分隔消息
- process,只显示PID
- raw,显示原生日志信息,没有其他元数据字段
- tag,只显示优先级/标记
- thread,显示优先级、PID、TID
- threadtime,显示日期、调用时间、优先级、标记、PID、TID(默认)
- time显示日期、调用时间、优先级、标记、PID
日志缓冲区
android日志记录系统为日志消息保留了多个环形缓冲区,并非所有消息都会发送到默认的环形缓冲区
adb logcat -b <buffer>
查看任意缓冲区
adb logcat -b <buffer> -b <buffer> -b <buffer>
adb logcat -b <buffer>、<buffer>、<buffer>
,查看多个缓冲区
- radio:包含无线装置、电话相关消息的缓冲区
- events:已经过解译的二进制系统事件缓冲区消息
- main:主日志缓冲区(默认),不包含系统和崩溃日志消息
- system:系统日志缓冲区(默认)
- crash:崩溃日志缓冲区(默认)
- all:所有缓冲区
- defalut:报告main、system、crash缓冲区
ANR
Android developers🔗
触发ANR
Application Not Responding,应用无响应
一定时间内一些事件未得到有效响应或响应时间过长,系统就会出现ANR,系统会终止该进程并将堆栈转储到/data/anr
Android中应用响应性由Activity管理器和窗口管理器系统服务监控。当Android检测到一下某一条件时,便会显示相应ANR:
- 5秒内输入事件未响应
- broadcastreceiver在10秒内尚未执行完毕
避免ANR
Android应用通常完全在单线程中运行(默认为界面线程或主线程)。应用在界面线程汇总执行任何需要很长时间的操作都有可能触发ANR,因为应用没有给自己处理输入事件或intent广播的机会。
因此,在可能需要执行冗长操作的情况下,不应在界面线程中执行这些操作,而是应该创建工作线程并在其中执行大部分操作,让界面线程保持运行,阻止系统断定代码卡住。尤其是onCreate()
和 onResume()
等关键生命周期方法。
工作线程
使用场景:
- 长时间运行操作,如网络或数据库操作
- 计算成本高昂的操作,如调整位图大小
如果是数据库操作,应通过异步请求完成
ANR日志
定位无响应应用
1、/data/anr
下的转储文件
2、bugreport-BUILD_ID-DATE.txt
中查找am_anr
06-28 18:23:49.041 1000 1615 9666 I am_anr : [0,3297,com.android.systemui,818462221,Input dispatching timed out (eddf1c1 NavigationBar0 (server) is not responding. Waited 6293ms for MotionEvent(deviceId=4, source=0x00001002, displayId=0, action=DOWN, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, xCursorPosition=nan, yCursorPosition=nan, pointers=[0: (499.3, 492.6)]), policyFlags=0x62000000)]
3、logcat日志中查找ANR in
查看堆栈跟踪
找到ANR对应的堆栈跟踪,确定时间戳和PID,检查进程的主线程,主线程是了解ANR发生时系统正在做的事,不一定是导致ANR的真正原因。
死锁
线程 A 在等待线程 B 占用的某些资源,而线程 B 也在等待线程 A 占用的某些资源。
死锁的往往首先表现为ANR,日志中会有类似信息WATCHDOG KILLING SYSTEM PROCESS
。用户所见表现为设备重新启动,这种是运行时重启,并非真正的设备重新启动。(这两概念奇奇怪怪)
- 运行时重启,系统服务器死机并重启,设备返回到显示启动动画
- 设备重新启动,内核已崩溃,设备返回google启动徽标
线程粘滞:执行时间超过“粘滞线程最长时间”(默认是600秒)的线程。
activity
应用组件,提供屏幕与用户互动执行操作,activity通过 ActivityManager
运行进程
一个界面就是一个activity?
聚焦状态的activity,am_focused_activity
进程启动事件,Start proc
系统颠簸,am_proc_died
和am_proc_start
内存
设备物理内存是有显示的,因为管理随机存取存储器很重要
内存不足
内存不足时系统会终止某些进程来释放内存,但又会继续启动其他进程,因此可能导致系统颠簸。
内存不足还可能会减慢任务切换速度,并可能阻止进行返回尝试(返回任务被终止)。如果启动器被终止,那么,用户触摸主屏幕按钮时会重启,并在日志中记录启动器重新加载
am_low_memory
表示最后一个缓存的进程已终止
内存快照
内存快照是一种dumpstate,其中会列出正在运行的JAVA进程和本机进程,快照仅提供特定时刻的状态,快照之前的系统状况不一定好/坏
广播
应用生成广播,在当前应用内发送事件或向其他应用发送事件