ANR log 日志的抓取

本文介绍了Android系统中ANR(Application Not Responding)错误的原因及如何避免。包括如何抓取ANR的日志,以及如何通过多线程处理来避免主线程长时间阻塞导致的ANR现象。
部署运行你感兴趣的模型镜像

【Android】抓取log(anr)

1、anr问题的log一般都在/data/anr/目录下,使用如下命令即可导出log

adb pull /data/anr/traces.txt   d:/     =》意思是将手机上的traces.txt导出到电脑的d目录下

但是也会有该命令失效的时候。你能adb shell ls /data/anr/  看到该文件,但是导出时会提示该文件不存在,原因没有去跟,但是导出的方式可以如下:

1、adb shell 

2、cat  /data/anr/xxx   >/mnt/sdcard/yy/zz.txt   

3、exit

4、adb pull /mnt/sdcard/yy/zz.txt  d:  ,即可将文件导出到了d盘。

==============================================================================

ANRs (“Application Not Responding”),意思是”应用没有响应“。


 

在如下情况下,Android会报出ANR错误:

– 主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件

– BroadcastReceiver 没有在10秒内完成返回

通常情况下,下面这些做法会导致ANR

 

1、在主线程内进行网络操作

2、在主线程内进行一些缓慢的磁盘操作(例如执行没有优化过的SQL查询)

应用应该在5秒或者10秒内响应,否则用户会觉得“这个应用很垃圾”“烂”“慢”…等等

逻辑应该是
1. new出一个新的线程,进行数据请求
2. 获取数据后,调用handler.sendMessage方法
3. 在handler的handle()方法中更新UI

 

这样就可以,或者也可以这样
private Thread mthread;
private Handler mhandler;
oncreate:
mthread = new Thread(runnable);//这里是在主线程中创建一个子线程,不会阻塞UI
mthread.start();

private Runnable runnable = new Runnable (){
           void run(){
                //做耗时的数据处理
                //处理完毕
                mhandler.sendEmptyMessge(1000);//这里发消息通知UI可以更新了
           }

};

mhandler = new Handler(){
              void handleMessgae(Message msg){
                    if(msg.what == 1000){
                        //更新UI
                    }
                    super.handlMessgae();
              }
};


您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

在 Android 开发中,**ANR(Application Not Responding)** 是指主线程长时间未响应用户输入或系统回调的错误。当发生 ANR 时,系统会生成日志文件用于分析原因。 你可以通过以下几种方式**自己抓取 ANR 日志**: --- ### ✅ 方法一:使用 `adb` 命令从设备中提取 ANR 日志 ANR 日志默认保存在设备的特定路径下,可以通过 `adb pull` 命令导出。 #### 步骤如下: ```bash # 1. 查看最近的 ANR 日志内容 adb shell cat /data/anr/anr_*.txt # 或者列出所有 anr 文件 adb shell ls /data/anr/ # 示例输出: # /data/anr/anr_2025-04-05-14-30-22-123.txt ``` > ⚠️ 注意:某些设备(尤其是非 root 的手机)可能限制访问 `/data/anr/` 目录,你需要有 **root 权限** 才能读取这些文件。 #### 如果你有 root 权限,可以直接拉取: ```bash # 拉取所有 anr 日志到本地当前目录 adb root # 请求重启 adbd 为 root 模式(部分设备支持) adb remount adb pull /data/anr ./anr_logs/ ``` 这会将所有 ANR 日志复制到你电脑上的 `./anr_logs/` 文件夹中。 --- ### ✅ 方法二:主动触发并捕获 ANR(测试用) 如果你想测试 ANR 抓取流程,可以手动制造一个 ANR: #### 示例代码(在主线程中休眠): ```java new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { // 主线程阻塞超过 5 秒,可能引发 ANR try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }, 2000); ``` 然后操作 App 触发该逻辑,并等待系统弹出 “App isn’t responding” 对话框 —— 此时 ANR 已经被记录。 再执行上面的 `adb pull /data/anr/...` 即可获取日志。 --- ### ✅ 方法三:通过 `adb logcat` 实时监控 ANR 信息 虽然完整的 ANR 调用栈存储在 `/data/anr/`,但 `logcat` 中也会打印关键提示。 ```bash # 实时查看日志 adb logcat | grep -i anr # 或保存到文件 adb logcat -v threadtime > logcat_output.txt ``` 当你看到类似输出时,说明发生了 ANR: ``` 04-05 14:30:22.123 1234 5678 E ActivityManager: ANR in com.example.myapp 04-05 14:30:22.123 1234 5678 E ActivityManager: PID: 9012 04-05 14:30:22.123 1234 5678 E ActivityManager: Reason: Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.) 04-05 14:30:22.123 1234 5678 E ActivityManager: Load: 5.00 / 4.50 / 4.00 04-05 14:30:22.123 1234 5678 E ActivityManager: CPU usage from 0ms to 8000ms ago: ``` ⚠️ 注意:这只是摘要,完整堆栈仍需查看 `/data/anr/` 下的文件。 --- ### ✅ 方法四:程序化监听 ANR(高级技巧) 虽然不能直接“监听”ANR,但你可以通过监测主线程卡顿来预警: #### 使用 `StrictMode` 或 `Choreographer` 检测掉帧: ```java public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() { private long lastFrameTimeNanos = System.nanoTime(); @Override public void doFrame(long frameTimeNanos) { long elapsedMs = (frameTimeNanos - lastFrameTimeNanos) / 1_000_000; if (elapsedMs > 16.6) { // 超过一帧时间(60fps) Log.w("FrameDrop", "Dropped frame! Took " + elapsedMs + "ms"); } lastFrameTimeNanos = frameTimeNanos; // 继续监听下一帧 Choreographer.getInstance().postFrameCallback(this); } }); } } ``` 这类方法可用于提前发现可能导致 ANR 的性能问题。 --- ### ✅ 方法五:使用第三方工具自动收集 ANR 如: - **Firebase Crashlytics**(支持非崩溃异常上报) - **Bugly(腾讯)** - **友盟+、听云、NewRelic** 它们可以在应用内监听文件变化或 hook 系统行为,自动上传 ANR 日志。 例如 Bugly 可以自动采集 `/data/anr/` 目录下的日志并上传服务器。 --- ### ANR 日志内容解析示例 一个典型的 ANR 日志包含以下信息: ```txt ----- pid 9012 at 2025-04-05 14:30:22 ----- Cmd line: com.example.myapp Build fingerprint: 'xxx' ABI: 'arm64-v8a' ... CPU usage from 0ms to 8000ms later: 85% 9012 com.example.myapp: 75% user + 10% kernel 15% system_server: 5% user + 10% kernel Dalvik threads (mutexes), native stacks, and traces: "main" prio=5 tid=1 Native | group="main" sCount=1 dsCount=0 flags=1 obj=0x7fabc12340 self=0xb0c12340 | sysTid=9012 nice=-10 cgrp=default sched=0/0 handle=0xb0c23450 | state=S schedstat=( 123456789 123456789 1234 ) utm=12 stm=11 core=2 HZ=100 | stack=0xbe3d4000-0xbe3d6000 remaining=104536B | held mutexes= native: #00 pc 0004a1b0 system/lib/libc.so (__poll_once_timed+32) native: #01 pc 0001e2c4 system/lib/libutils.so (android::Looper::pollInner(int)+140) native: #02 pc 0001e124 system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+44) native: #03 pc 00123abc system/lib/libandroid_runtime.so (android::NativeMessageQueue::pollOnce(_JNIEnv*, int)+...) at android.os.MessageQueue.nativePollOnce(Native method) at android.os.MessageQueue.next(MessageQueue.java:336) at android.os.Looper.loop(Looper.java:176) at android.app.ActivityThread.main(ActivityThread.java:7690) at java.lang.reflect.Method.invoke(Native method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) ``` 重点关注 `"main"` 线程的调用栈是否卡在某处(比如死锁、耗时操作、JNI 阻塞等)。 --- ### 总结:如何高效抓取 ANR 日志? | 方法 | 是否需要 root | 适用场景 | |------|----------------|----------| | `adb pull /data/anr/` | 是(大多数情况) | 最准确完整的方法 | | `adb logcat \| grep ANR` | 否 | 快速查看概要 | | 制造 ANR 并提取 | 是 | 测试调试阶段 | | 第三方 SDK 自动收集 | 否 | 上线后线上监控 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值