【ClaudeCode】Android APK ANR解析示例

张开发
2026/4/10 11:10:27 15 分钟阅读

分享文章

【ClaudeCode】Android APK ANR解析示例
ANR原文件----- pid 5532 at 2026-03-27 18:10:31 ----- Cmd line: com.g.g.wdapp Build fingerprint: g/a100/a100:11/260326:userdebug/test-keys ABI: arm64 Build type: optimized Zygote loaded classes15795 post zygote classes300 Dumping registered class loaders #0 dalvik.system.PathClassLoader: [], parent #1 #1 java.lang.BootClassLoader: [], no parent #2 dalvik.system.PathClassLoader: [/system/app/wdapp/wdapp.apk], parent #1 Done dumping class loaders Classes initialized: 229 in 46.286ms Intern table: 32236 strong; 543 weak JNI: CheckJNI is off; globals671 (plus 51 weak) Libraries: /system/app/wdapp/lib/arm64/lib_jnicli_test.so libandroid.so libaudioeffect_jni.so libcompiler_rt.so libicu_jni.so libjavacore.so libjavacrypto.so libjnigraphics.so libmedia_jni.so libopenjdk.so librs_jni.so libsfplugin_ccodec.so libsoundpool.so libstats_jni.so libwebviewchromium_loader.so (15) Heap: 88% free, 3211KB/26MB; 85201 objects Dumping cumulative Gc timings Average major GC reclaim bytes ratio inf over 0 GC cycles Average major GC copied live bytes ratio 0.718828 over 3 major GCs Cumulative bytes moved 9935608 Cumulative objects moved 186863 Peak regions allocated 50 (12MB) / 768 (192MB) Start Dumping histograms for 1 iterations for young concurrent copying ProcessMarkStack: Sum: 3.839ms 99% C.I. 3.839ms-3.839ms Avg: 3.839ms Max: 3.839ms ScanImmuneSpaces: Sum: 3.134ms 99% C.I. 3.134ms-3.134ms Avg: 3.134ms Max: 3.134ms VisitConcurrentRoots: Sum: 1.195ms 99% C.I. 1.195ms-1.195ms Avg: 1.195ms Max: 1.195ms SweepSystemWeaks: Sum: 475us 99% C.I. 475us-475us Avg: 475us Max: 475us ClearFromSpace: Sum: 373us 99% C.I. 373us-373us Avg: 373us Max: 373us GrayAllDirtyImmuneObjects: Sum: 229us 99% C.I. 229us-229us Avg: 229us Max: 229us InitializePhase: Sum: 222us 99% C.I. 222us-222us Avg: 222us Max: 222us FlipOtherThreads: Sum: 158us 99% C.I. 158us-158us Avg: 158us Max: 158us ScanCardsForSpace: Sum: 104us 99% C.I. 104us-104us Avg: 104us Max: 104us ForwardSoftReferences: Sum: 83us 99% C.I. 83us-83us Avg: 83us Max: 83us VisitNonThreadRoots: Sum: 68us 99% C.I. 68us-68us Avg: 68us Max: 68us EnqueueFinalizerReferences: Sum: 56us 99% C.I. 56us-56us Avg: 56us Max: 56us ProcessReferences: Sum: 31us 99% C.I. 4us-27us Avg: 15.500us Max: 27us RecordFree: Sum: 30us 99% C.I. 0.250us-30us Avg: 15us Max: 30us (Paused)GrayAllNewlyDirtyImmuneObjects: Sum: 18us 99% C.I. 18us-18us Avg: 18us Max: 18us SweepArray: Sum: 15us 99% C.I. 15us-15us Avg: 15us Max: 15us CopyingPhase: Sum: 12us 99% C.I. 12us-12us Avg: 12us Max: 12us (Paused)ClearCards: Sum: 10us 99% C.I. 250ns-9000ns Avg: 500ns Max: 9000ns ResetStack: Sum: 8us 99% C.I. 8us-8us Avg: 8us Max: 8us FreeList: Sum: 7us 99% C.I. 7us-7us Avg: 7us Max: 7us EmptyRBMarkBitStack: Sum: 6us 99% C.I. 6us-6us Avg: 6us Max: 6us UnBindBitmaps: Sum: 5us 99% C.I. 5us-5us Avg: 5us Max: 5us MarkZygoteLargeObjects: Sum: 4us 99% C.I. 4us-4us Avg: 4us Max: 4us (Paused)FlipCallback: Sum: 3us 99% C.I. 3us-3us Avg: 3us Max: 3us (Paused)SetFromSpace: Sum: 2us 99% C.I. 2us-2us Avg: 2us Max: 2us ResumeOtherThreads: Sum: 0 99% C.I. 0ns-0ns Avg: 0ns Max: 0ns Done Dumping histograms young concurrent copying paused: Sum: 46us 99% C.I. 46us-46us Avg: 46us Max: 46us young concurrent copying freed-bytes: Avg: 3089KB Max: 3089KB Min: 3089KB Freed-bytes histogram: 2560:1 young concurrent copying total time: 10.119ms mean time: 10.119ms young concurrent copying freed: 36725 objects with total size 3089KB young concurrent copying throughput: 3.6725e06/s / 301MB/s per cpu-time: 351463111/s / 335MB/s Average minor GC reclaim bytes ratio 8.73945 over 1 GC cycles Average minor GC copied live bytes ratio 0.0139294 over 11 minor GCs Cumulative bytes moved 606080 Cumulative objects moved 12448 Peak regions allocated 50 (12MB) / 768 (192MB) Total time spent in GC: 10.119ms Mean GC size throughput: 298MB/s per cpu-time: 325MB/s Mean GC object throughput: 3.62931e06 objects/s Total number of allocations 121926 Total bytes allocated 6300KB Total bytes freed 3089KB Free memory 23MB Free memory until GC 23MB Free memory until OOME 188MB Total memory 26MB Max memory 192MB Zygote space size 3148KB Total mutator paused time: 46us Total time waiting for GC to complete: 2.815us Total GC count: 1 Total GC time: 10.119ms Total blocking GC count: 0 Total blocking GC time: 0 Histogram of GC count per 10000 ms: 0:1 Histogram of blocking GC count per 10000 ms: 0:1 Native bytes total: 12137756 registered: 142844 Total native bytes at last GC: 5283848 /system/app/wdapp/oat/arm64/wdapp.odex: quicken /system/framework/oat/arm64/android.hidl.manager-V1.0-java.odex: quicken /system/framework/oat/arm64/android.hidl.base-V1.0-java.odex: quicken /system/framework/oat/arm64/android.test.base.odex: quicken Current JIT code cache size (used / resident): 106KB / 108KB Current JIT data cache size (used / resident): 99KB / 104KB Zygote JIT code cache size (at point of fork): 44KB / 48KB Zygote JIT data cache size (at point of fork): 41KB / 44KB Current JIT mini-debug-info size: 68KB Current JIT capacity: 256KB Current number of JIT JNI stub entries: 0 Current number of JIT code cache entries: 113 Total number of JIT compilations: 79 Total number of JIT compilations for on stack replacement: 3 Total number of JIT code cache collections: 2 Memory used for stack maps: Avg: 282B Max: 1992B Min: 24B Memory used for compiled code: Avg: 1545B Max: 9672B Min: 52B Memory used for profiling info: Avg: 391B Max: 4736B Min: 32B Start Dumping histograms for 121 iterations for JIT timings Compiling: Sum: 167.071ms 99% C.I. 0.038ms-9.928ms Avg: 1.403ms Max: 10.834ms TrimMaps: Sum: 6.198ms 99% C.I. 5us-370.250us Avg: 52.084us Max: 377us Code cache collection: Sum: 2.744ms 99% C.I. 0.675ms-2.069ms Avg: 1.372ms Max: 2.069ms Done Dumping histograms Memory used for compilation: Avg: 174KB Max: 1037KB Min: 20KB ProfileSaver total_bytes_written0 ProfileSaver total_number_of_writes0 ProfileSaver total_number_of_code_cache_queries0 ProfileSaver total_number_of_skipped_writes0 ProfileSaver total_number_of_failed_writes0 ProfileSaver total_ms_of_sleep5000 ProfileSaver total_ms_of_work0 ProfileSaver total_number_of_hot_spikes1 ProfileSaver total_number_of_wake_ups1 suspend all histogram: Sum: 74us 99% C.I. 1us-16us Avg: 4.352us Max: 16us DALVIK THREADS (16): Signal Catcher daemon prio10 tid6 Runnable | groupsystem sCount0 dsCount0 flags0 obj0x131c01b0 self0xb400f3287fe09f50 | sysTid5552 nice-20 cgrpdefault sched0/0 handle0xf3270056fcc0 | stateR schedstat( 8463442 10273281 5 ) utm0 stm0 core1 HZ100 | stack0xf32700478000-0xf3270047a000 stackSize995KB | held mutexes mutator lock(shared held) native: #00 pc 00000000004a1f20 /apex/com.android.art/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostreamchar, std::__1::char_traitschar , int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)140) native: #01 pc 00000000005af0f0 /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostreamchar, std::__1::char_traitschar , bool, BacktraceMap*, bool) const376) native: #02 pc 00000000005cc228 /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)924) native: #03 pc 00000000005c6168 /apex/com.android.art/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)528) native: #04 pc 00000000005c5334 /apex/com.android.art/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostreamchar, std::__1::char_traitschar , bool)1920) native: #05 pc 00000000005c47d4 /apex/com.android.art/lib64/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostreamchar, std::__1::char_traitschar )776) native: #06 pc 0000000000570794 /apex/com.android.art/lib64/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostreamchar, std::__1::char_traitschar )196) native: #07 pc 0000000000585d28 /apex/com.android.art/lib64/libart.so (art::SignalCatcher::HandleSigQuit()1396) native: #08 pc 0000000000584cf4 /apex/com.android.art/lib64/libart.so (art::SignalCatcher::Run(void*)348) native: #09 pc 00000000000afd4c /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)64) native: #10 pc 0000000000050288 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread64) (no managed stack frames) main prio5 tid1 Native | groupmain sCount1 dsCount0 flags1 obj0x71b06758 self0xb400f3287fe067b0 | sysTid5532 nice0 cgrpdefault sched0/0 handle0xf329a68ae4f8 | stateS schedstat( 259191045 91807139 750 ) utm21 stm4 core3 HZ100 | stack0xffffdf058000-0xffffdf05a000 stackSize8192KB | held mutexes native: #00 pc 000000000009af78 /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl8) native: #01 pc 0000000000057c60 /apex/com.android.runtime/lib64/bionic/libc.so (ioctl156) native: #02 pc 0000000000051ae4 /system/lib64/libbinder.so (android::IPCThreadState::talkWithDriver(bool)296) native: #03 pc 0000000000052ad0 /system/lib64/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)60) native: #04 pc 0000000000052840 /system/lib64/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const, android::Parcel*, unsigned int)184) native: #05 pc 000000000004b114 /system/lib64/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const, android::Parcel*, unsigned int)152) native: #06 pc 00000000001253a8 /system/lib64/libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int)152) at android.os.BinderProxy.transactNative(Native method) at android.os.BinderProxy.transact(BinderProxy.java:550) at gateway.IGateway$Stub$Proxy.setFuncIdProperty(IGateway.java:186) at com.g.g.wdapp.GatewayAidlServiceImpl.stoptest(GatewayAidlServiceImpl.java:263) at com.g.g.wdapp.TestAppService.stoptest(TestAppService.java:363) at com.g.g.wdapp.TestAppService.stoptest(TestAppService.java:341) at com.g.g.wdapp.FloatingViewImpl$2.onClick(FloatingViewImpl.java:115) at android.view.View.performClick(View.java:7455) at android.view.View.performClickInternal(View.java:7432) at android.view.View.access$3600(View.java:812) at android.view.View$PerformClick.run(View.java:28335) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7700) at java.lang.reflect.Method.invoke(Native method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)分析结果esc to interrupt ▒ Claude Code╭─── Claude Code v2.1.97 ─────────────────────────────────────────────────────────────────────╮ │ │ Tips for getting started │ │ Welcome back! │ Run /init to create a CLAUDE.md file with instructions for Claude │ │ │ ───────────────────────────────────────────────────────────────── │ │ ▐▛███▜▌ │ Recent activity │ │ ▝▜█████▛▘ │ No recent activity │ │ ▘▘ ▝▝ │ │ │ │ │ │ qwen3.5-plus · API Usage Billing │ │ │ D:\claude │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ 分析anr_2026-03-27-18-10-31-365 ● 我来帮你分析这个 ANR (Application Not Responding) 文件。首先让我读取这个文件的内容。 Read 1 file (ctrlo to expand) ● 文件比较大1.8MB让我先读取文件的关键部分来分析。ANR 文件通常头部包含关键信息让我分段读取 Searched for 1 pattern, read 1 file (ctrlo to expand) ● 让我继续读取更多关键信息特别是关于主线程和其他阻塞的线程 Searched for 1 pattern, read 1 file (ctrlo to expand) ● 现在让我读取主线程的更多详细信息以及 Blocked 状态的线程 Read 1 file (ctrlo to expand) ● 现在让我查看 system_server 中是否有阻塞相关的关键信息 Searched for 1 pattern (ctrlo to expand) ● 我已经有了足够的信息来进行分析。让我总结这个 ANR 的关键发现 ANR 详细分析报告 b 关键信息摘要 ┌────────────┬─────────────────────────────┐ │ 项目 │ 值 │ ├────────────┼─────────────────────────────┤ │ ANR 时间 │ 2026-03-27 18:10:31 │ ├────────────┼─────────────────────────────┤ │ 进程包名 │ com.g.g.wdapp │ ├────────────┼─────────────────────────────┤ │ PID │ 5532 │ ├────────────┼─────────────────────────────┤ │ 设备版本 │ Android 11 (API 30) │ ├────────────┼─────────────────────────────┤ │ ABI │ arm64 │ ├────────────┼─────────────────────────────┤ │ 主线程 Tid │ 5532 │ ├────────────┼─────────────────────────────┤ │ 主线程状态 │ S (Sleeping - 不可中断睡眠) │ └────────────┴─────────────────────────────┘ --- 问题根因分析 主线程堆栈追踪 main prio5 tid1 Native | stateS ← 阻塞状态 | stack0xffffdf058000-0xffffdf05a000 stackSize8192KB at android.os.BinderProxy.transact(Native) at android.os.BinderProxy.transact(BinderProxy.java:550) at gateway.IGateway$Stub$Proxy.setFuncIdProperty(IGateway.java:186) ↑ 跨进程 AIDL 调用 at com.g.g.wdapp.GatewayAidlServiceImpl.stoptest(GatewayAidlServiceImpl.java:263) at com.g.g.wdapp.TestAppService.stoptest(TestAppService.java:363) at com.g.g.wdapp.TestAppService.stoptest(TestAppService.java:341) at com.g.g.wdapp.FloatingViewImpl$2.onClick(FloatingViewImpl.java:115) ↑ 用户点击悬浮窗按钮触发 at android.view.View.performClick(View.java:7455) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7700) 调用链路图 ┌─────────────────────────────────────────────────────────┐ │ 用户点击悬浮窗按钮 │ │ FloatingViewImpl.java:115 onClick() │ └────────────────────┬────────────────────────────────────┘ │ UI Thread (主线程) ▼ ┌─────────────────────────────────────────────────────────┐ │ TestAppService.java:341/363 stoptest() │ │ 业务逻辑处理 │ └────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ GatewayAidlServiceImpl.java:263 stoptest() │ │ 调用 AIDL 接口 │ └────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ IGateway.setFuncIdProperty() │ │ ★ 跨进程 Binder 调用 (同步阻塞) │ └────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Binder 驱动 ioctl 等待 │ │ ★ 远端服务无响应/响应超时 → ANR │ └─────────────────────────────────────────────────────────┘ --- 问题诊断 ANR 类型: Binder IPC 同步阻塞 阻塞原因: 1. 主线程通过 AIDL 同步调用远端 gateway 服务的 setFuncIdProperty 方法 2. 远端服务处理缓慢、死锁或无响应导致 Binder 事务无法返回 3. 主线程等待超过 5 秒 (Android ANR 阈值)系统触发 ANR 为何严重: - 主线程负责 UI 渲染和事件分发阻塞会导致界面卡死 - Binder 默认超时时间为 5 秒正好触发 ANR 阈值 --- 详细修复方案 方案一异步调用 (推荐) 修改 TestAppService.java: // ❌ 错误写法 - 主线程同步调用 public void stoptest() { // 直接调用 AIDL阻塞主线程 mGateway.setFuncIdProperty(funcId); // ... 其他逻辑 } // ✅ 正确写法 - 后台线程异步调用 public void stoptest() { // 使用线程池/HandlerThread/协程 Executors.newSingleThreadExecutor().execute(() - { try { mGateway.setFuncIdProperty(funcId); // 通过 Handler 回调到主线程更新 UI new Handler(Looper.getMainLooper()).post(() - { // UI 更新逻辑 }); } catch (RemoteException e) { Log.e(TAG, setFuncIdProperty failed, e); } }); } 或使用 Kotlin 协程 (如果项目使用 Kotlin): fun stoptest() { lifecycleScope.launch { withContext(Dispatchers.IO) { // 在 IO 线程执行 Binder 调用 mGateway.setFuncIdProperty(funcId) } // 回到主线程 updateUi() } } --- 方案二修改 AIDL 接口为 oneway 异步 修改 IGateway.aidl: // ❌ 当前同步接口 interface IGateway { void setFuncIdProperty(String funcId); } // ✅ 改为 oneway 异步接口 interface IGateway { oneway void setFuncIdProperty(String funcId); } 注意: - oneway 方法调用后立即返回不等待服务端处理 - 需要服务端支持回调机制来通知处理结果 - 适用于不关心执行结果的场景 --- 方案三添加超时机制 public void stoptest() { CountDownLatch latch new CountDownLatch(1); AtomicBoolean success new AtomicBoolean(false); new Thread(() - { try { mGateway.setFuncIdProperty(funcId); success.set(true); } catch (RemoteException e) { Log.e(TAG, Call failed, e); } finally { latch.countDown(); } }).start(); try { // 最多等待 3 秒避免 ANR if (!latch.await(3, TimeUnit.SECONDS)) { Log.w(TAG, Gateway call timeout); // 处理超时逻辑 } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } --- 修复优先级 ┌────────┬─────────────────────┬────────────────────────────────┬────────┐ │ 优先级 │ 方案 │ 适用场景 │ 复杂度 │ ├────────┼─────────────────────┼────────────────────────────────┼────────┤ │ P0 │ 方案一异步调用 │ 通用方案适用于所有场景 │ 低 │ ├────────┼─────────────────────┼────────────────────────────────┼────────┤ │ P1 │ 方案二oneway 接口 │ 不关心执行结果的场景 │ 中 │ ├────────┼─────────────────────┼────────────────────────────────┼────────┤ │ P1 │ 方案三超时机制 │ 需要同步等待结果但可降级的场景 │ 中 │ └────────┴─────────────────────┴────────────────────────────────┴────────┘ --- ✅ 验证清单 修复后需验证: - 点击悬浮窗按钮后 UI 保持响应 - setFuncIdProperty 调用在 1 秒内完成 - 远端 gateway 服务正常工作 - 异常场景有适当的错误处理 - 连续多次点击不会导致新的阻塞

更多文章