mysql中logcat_Monkey+Logcat+traces 查找以及分析定位 ANR 问题 (四)

本文介绍了如何使用adb logcat命令捕获并分析Android应用程序的ANR问题,包括理解日志缓冲区、日志结构以及如何通过traces文件定位ANR的关键信息,为解决问题提供了详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注:文章有说的不对的地方,大家可以帮忙指出!

adb logcat 作用:

把设备上的操作实时打印出来,比如 app 崩溃/异常,显示崩溃的原因,如空指针、参数错误、下标越界等。

操作步骤:

打开窗口 1,执行:adb logcat 获取 log,如果要保存文件,加上> /路径/新建后缀为.log的文件

结合 monkey 操作,重新打开窗口 2,执行 monkey 命令

monkey 测试执行结束时,立刻在窗口 1 上输入快捷键ctrl+c

logcat 日志详细解析

--------- beginning of xxxx

解析:日志以--------- beginning of xxxx为起点,开始捕捉 Android 日志。xxx 对应这存储着 Android 日志记录器的环形缓冲区。Android 系统在运行时会时刻在几个设备文件中的一个中写入字符串。而这几个设备文件指向几个环形缓冲区。这是 Android 日志的记录原理。而这几个缓冲区合称日志记录器缓冲区。

扩展,讲讲 logcat 缓冲区 log。

logcat 缓冲区介绍: android log 输出量巨大,特别是通信系统的 log, 缓冲区主要给系统组件使用,一般的应用不需要关心,应用的 log 都输出到 main 缓冲区中 .

1. Radio:无线电,无线网络设备/电话通讯相关 log

2. System:系统,系统组件或系统应用的 log

3. Event:事件,事件/监听相关 log

4. Main:主要,所有 java 层的 log,遗迹不属于上面 3 层的 log

5. Crash:崩溃,应用崩溃时在此写入崩溃信息 log

注意:使用命令adb logcat -b default时(显示默认的缓冲区 log),未特殊指定缓冲区名称,指 main,system,crash 缓冲区的 log。

如图:

02-10 10:13:14.234 21857 18515 E AndroidRuntime: FATAL EXCEPTION: URGENT_THREAD_540

我给大家大概翻译下:

1. 日志时间:02-10 10:13:14.234

2. PID(进程 ID):21857

3. TID(线程 ID):18515

4. 优先级:E

5. 便签:AndroidRuntime

6. 正文日志:FATAL EXCEPTION: URGENT_THREAD_540

现在我再针对这句话给大家进行详细的说明(不带任何参数的 logcat 命令):

默认输出的日志格式:(不带任何参数的 logcat 命令)

由六部分组成:

1. 写下日志时的时间,如上中 07-22 20:31:21.565。

2. PID(进程 ID),如上中 993。

3. TID(线程 ID),如上中 1032。

4. 优先级,在 Android 中,日志的优先级从低到高分以下几种:

2600.svg V—Verbose(啰嗦,最低级别,开发调试中的一些详细信息,仅在开发中使用,不可在发布产品中输出,不是很常见,包含诸如方法名,变量值之类的信息)

2600.svg D—Debug(调试,用于调试的信息,可以在发布产品中关闭,比较常见,开发中经常选择输出此种级别的日志,有时在 beta 版应用中出现)

2600.svg I—Info(信息,该等级日志显示运行状态信息,可在产品出现问题时提供帮助,从该级别开始的日志通常包含完整意义的英语语句和调试信息,是最常见的日志级别)

2600.svg W—Warning(警告,运行出现异常即将发生错误或表明已发生非致命性错误,该级别日志通常显示出执行过程中的意外情况,例如将 try-catch 语句块中的异常打印堆栈轨迹之后可输出此种级别日志)

2600.svg E—Error(错误,已经出现可影响运行的错误,比如应用 crash 时输出的日志)

2600.svg F—Fatal(严重错误,比 error 级别更高,目前我只在 android 系统内核发出的日志中看到此种级别。在 Android6.0 以前表明开发者认为绝对不应该出现的错误,在此以后一般开发场景下绝不应该输出此种级别的日志)

2600.svg S—Silent(寂静,最高级别,没有一条日志会属于这个级别,仅仅作为关闭 logcat 输出的过滤器参数)

示例中日志等级显示为 W,表示警告级别。

5. 标签,标明日志发起者和方便日志的过滤筛选,如上中 BroadcastQueue,表示该日志关于广播队列。

6. 正文,本日志的主体内容。示例日志中表示一个后台执行被阻止,并显示出了接收到的意图的详细信息。

从 logcat.log 中发现内存泄漏方法(上节遗留)

在 logcat.log 中搜索关键词 GC,如果有下面四个中的一个,就可能存在内存泄露。

GC_FOR_ALLOC, 因为在分配内存时内存丌够引发的

GC_EXPLICIT, 表明 GC 被显式请求触发的,如 System.gc 调用

GC_CONCURRENT, 表明 GC 在内存使用率达到一定的警戒值时,自动触发。

GC_BEFORE_OOM, 表明在虚拟机抛出内存丌够异常OOM之前,执行最后一次回收内存垃圾

举例:

02-27 14:42:52.544 I/art ( 1844): Background sticky concurrent mark sweep GC freed 181925(7MB) AllocSpace objects, 0(0B) LOS objects, 9% free, 74MB/82MB, paused 2.857ms total 104.330ms

解析:Gson 序列化问题导致的内存溢出,问题原因,如果在 json model 里面放了非可序列化的对象就会导致这中问题,可序列化的就是那些基础数据类型和集合类型,如果在里面放个 Android 的 Activity 或者 adapter 这类类型字段,变量声明前面一定要加

transient,否则就是长期 GC 提示。

从 logcat.log 中查找 ANR 以及 ForceClosed 等异常退出问题

如果是 ANR 问题 , 则搜索 “ANR ” 关键词 (ANR 后加个空格,屏蔽掉 anr.log 文件的无效信息) 。 快速定位到关键事件信息 。

如果是 ForceClosed 和其它异常退出信息,则搜索"Fatal" 关键词, 快速定位到关键事件信息 。

定位到关键事件信息后 , 如果信息不够明确的,再去搜索应用程序包的虚拟机信息 ,查看具体的进程和线程跟踪的日志,来定位到代码 。

traces 日志中 ANR 的定位与分析

当 ANR 发生时除过 logcat 可以看见的 log 以外,我们还可以在系统指定目录下找到 traces 文件进行分析,获取 ANR trace 文件:

adb pull /data/anr/traces.txt /Users/weixiangyang/Desktop/

分析虚拟机信息,搜索Dalvik Thread关键词,快速定位到本应用程序的虚拟机信息日志,如下:

//显示进程id、ANR发生时间点、ANR发生进程包名

----- pid 8562 at 2018-03-03 14:39:49 -----

Cmd line: com.taobao.taobao

//一些GC等object信息,通常可以忽略

......

//ANR方法堆栈打印信息!重点!

DALVIK THREADS (132):

"main" prio=5 tid=1 Native

| group="main" sCount=1 dsCount=0 obj=0x787c5000 self=0x7f8e696a00

| sysTid=1786 nice=-10 cgrp=default sched=0/0 handle=0x7f92c45aa0

| state=S schedstat=( 0 0 0 ) utm=17421 stm=10643 core=4 HZ=100

| stack=0x7fcaf1e000-0x7fcaf20000 stackSize=8MB

| held mutexes=

kernel: (couldn't read /proc/self/task/1786/stack)

native: #00 pc 0000000000078230 /system/lib64/libc.so (__epoll_pwait+8)

native: #01 pc 000000000001e80c /system/lib64/libc.so (epoll_pwait+64)

native: #02 pc 00000000000185c0 /system/lib64/libutils.so (_ZN7android6Looper9pollInnerEi+160)

native: #03 pc 0000000000018460 /system/lib64/libutils.so (_ZN7android6Looper8pollOnceEiPiS1_PPv+60)

native: #04 pc 00000000000f2d24 /system/lib64/libandroid_runtime.so (_ZN7android18NativeMessageQueue8pollOnceEP7_JNIEnvP8_jobjecti+48)

native: #05 pc 0000000000b790b0 /system/framework/arm64/boot-framework.oat (Java_android_os_MessageQueue_nativePollOnce__JI+140)

//真正导致ANR的问题点

at android.os.MessageQueue.nativePollOnce(Native method)

at android.os.MessageQueue.next(MessageQueue.java:323)

at android.os.Looper.loop(Looper.java:142)

at com.android.server.SystemServer.run(SystemServer.java:377)

at com.android.server.SystemServer.main(SystemServer.java:239)

at java.lang.reflect.Method.invoke!(Native method)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:791)

......

//省略一些不常关注堆栈打印

每一段都是一个线程 。通过分析发现关键问题,到这里就可以找开发协助,深入代码具体分析,将 traces 日志,logcat 有问题的日志进行整理,发给开发即可!

### Android 开发中 ANR 分析与解决方案 #### 获取 `trace.txt` 文件 当应用程序未响应 (ANR) 发生时,Android 系统会在 `/data/anr/` 路径下生成名为 `traces.txt` 的日志文件。此文件包含了所有线程的堆栈信息,尤其是主线程的状态,有助于定位导致 ANR 的根本原因[^2]。 为了从设备中提取该文件,可以使用 ADB 命令: ```bash adb pull /data/anr/traces.txt ``` 此外,在每次发生 ANR 事件时,Logcat 日志也会记录 `trace.txt` 文件的具体路径。某些集成开发环境(IDE),如 Android Studio,允许开发者在程序运行期间直接查看这些 ANR 信息。 #### 分析 `trace.txt` 结构 `trace.txt` 文件通常由多个部分组成,每一部分对应一个进程内的不同线程状态。对于每个线程而言,文件会显示其名称、优先级以及当前正在执行的方法调用链路。特别需要注意的是 "main" 或者 "UI thread" 下的内容,因为大多数情况下,ANR 是由于长时间阻塞 UI 线程而引起的。 #### 使用 StrictMode 进行预防性检测 为了避免潜在的应用无响应情况,建议在开发过程中利用 Android SDK 提供的 `StrictMode` 工具类来进行监控。通过配置合适的策略选项,能够及时捕获那些可能引发 ANR 的行为模式,比如在网络请求或磁盘读写操作发生在主线程上的情形。这使得开发者能够在早期阶段识别并修正此类问题[^3]。 #### 处理已发生的 ANR 错误 一旦确认了造成 ANR 的具体位置,则应采取措施优化相应代码逻辑,确保任何耗时任务都不会影响到用户体验流畅度。常见的改进方法包括但不限于: - 将耗时较长的任务移至后台工作队列; - 减少不必要的资源加载次数; - 对频繁访问的数据源实施缓存机制; - 合理规划异步回调函数的设计思路; 综上所述,通过对 `trace.txt` 文件的有效解读和借助像 `StrictMode` 这样的辅助工具,可以帮助我们更好地理解和应对 Android 应用中存在的 ANR 挑战[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值