Android anr 问题处理步骤
Anr 问题开发中比较常见,但是处理起来比较麻烦
下面总结anr问题的处理步骤一下:
1.收集logcat
anr出现的时候手机logcat会有提示,这里面会包括一些关键信息,需要收集起来
04-14 18:30:05.259 E/ActivityManager( 1601): ANR in com.cmft.cmuop.di (com.cmft.cmuop.di/com.cmft.coco.meetinglib.view.activity.CallActivity) (发生anr的包名和当前的Activity)
04-14 18:30:05.259 E/ActivityManager( 1601): PID: 19377(当前进程的pid)
04-14 18:30:05.259 E/ActivityManager( 1601): Reason: Input dispatching timed out (com.cmft.cmuop.di/com.cmft.coco.meetinglib.view.activity.CallActivity, Waiting because the touched window is paused.)(Anr原因,这个可以用来区分anr的类型)
04-14 18:30:05.259 E/ActivityManager( 1601): Parent: com.cmft.cmuop.di/com.cmft.coco.meetinglib.view.activity.CallActivity
04-14 18:30:05.259 E/ActivityManager( 1601): Load: 0.6 / 0.62 / 1.11
04-14 18:30:05.259 E/ActivityManager( 1601): CPU usage from 343ms to -19980ms ago (2021-04-14 18:29:44.872 to 2021-04-14 18:30:05.196) with 99% awake:
04-14 18:30:05.259 E/ActivityManager( 1601): 46% 557/logd: 27% user + 18% kernel / faults: 22 minor(手机的cpu总负载,如果很高需要注意是不是性能导致anr)
04-14 18:30:05.259 E/ActivityManager( 1601): 0.4% 1026/adbd: 0% user + 0.3% kernel / faults: 423 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 14% 19377/com.cmft.cmuop.di: 11% user + 2.5% kernel / faults: 3950 minor(发生anr的应用的cpu负载,如果很高需要注意是不是性能导致anr)
04-14 18:30:05.259 E/ActivityManager( 1601): 8.8% 1601/system_server: 4.2% user + 4.6% kernel / faults: 10472 minor 325 major
04-14 18:30:05.259 E/ActivityManager( 1601): 6.9% 1099/media.codec: 4.9% user + 2% kernel / faults: 39417 minor 83 major
04-14 18:30:05.259 E/ActivityManager( 1601): 6.7% 10569/com.tencent.qnet: 0.6% user + 6% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 5.9% 851/audioserver: 3.2% user + 2.6% kernel / faults: 208 minor 3 major
04-14 18:30:05.259 E/ActivityManager( 1601): 5.8% 17847/kworker/u16:14: 0% user + 5.8% kernel / faults: 10 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 0.5% 21814/kworker/u17:1: 0% user + 0.5% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 4.8% 21943/kworker/u16:4: 0% user + 4.8% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 12967/kworker/u17:0: 0% user + 0.1% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 4.1% 21787/kworker/u16:0: 0% user + 4.1% kernel / faults: 22 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 4% 758/android.hardware.audio@2.0-service: 0.6% user + 3.3% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 3.5% 20046/kworker/u16:1: 0% user + 3.5% kernel / faults: 1 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 1.5% 6875/kworker/u16:3: 0% user + 1.5% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 1% 11655/com.android.settings: 0.7% user + 0.2% kernel / faults: 6539 minor 6 major
04-14 18:30:05.259 E/ActivityManager( 1601): 1.4% 2220/com.android.systemui: 1% user + 0.3% kernel / faults: 3758 minor 6 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 147/kswapd0: 0% user + 0% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.8% 12186/com.miui.voiceassist: 0.4% user + 0.3% kernel / faults: 3329 minor 5 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 17097/kworker/u17:2: 0% user + 0% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 1.1% 856/surfaceflinger: 0.5% user + 0.5% kernel / faults: 423 minor 2 major
04-14 18:30:05.259 E/ActivityManager( 1601): 1% 779/android.hardware.sensors@1.0-service: 0.4% user + 0.5% kernel / faults: 178 minor 7 major
04-14 18:30:05.259 E/ActivityManager( 1601): 1% 1051/cnss_diag: 0.7% user + 0.2% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 1169/media.swcodec: 0% user + 0% kernel / faults: 7591 minor 36 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.8% 2507/com.android.phone: 0.3% user + 0.4% kernel / faults: 1437 minor 140 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.5% 17330/com.sohu.inputmethod.sogou.xiaomi: 0.4% user + 0.1% kernel / faults: 2893 minor 7 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 762/android.hardware.camera.provider@2.4-service_64: 0% user + 0% kernel / faults: 43 minor 3 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 15801/com.miui.securityinputmethod: 0% user + 0% kernel / faults: 3076 minor 1 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.3% 11554/kworker/u16:5: 0% user + 0.3% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.5% 1081/media.extractor: 0.1% user + 0.3% kernel / faults: 3486 minor 14 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.4% 770/android.hardware.graphics.composer@2.3-service: 0.2% user + 0.2% kernel / faults: 40 minor 4 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.3% 3673/com.android.nfc: 0.1% user + 0.1% kernel / faults: 1428 minor 39 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 21801/kworker/u16:2: 0% user + 0% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.3% 1083/mediaserver: 0% user + 0.2% kernel / faults: 99 minor 3 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.2% 782/android.hardware.wifi@1.0-service: 0% user + 0.1% kernel / faults: 51 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 0.2% 2405/com.android.browser: 0% user + 0.2% kernel / faults: 48 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 11697/com.miui.cloudservice: 0% user + 0% kernel / faults: 1827 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 17454/kworker/u16:10: 0% user + 0.1% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.2% 9/rcu_preempt: 0% user + 0.2% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 668/zygote: 0% user + 0% kernel / faults: 16 minor 1 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 4246/com.xiaomi.xmsf: 0% user + 0% kernel / faults: 202 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 12/rcuop/0: 0% user + 0.1% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 30/rcuop/2: 0% user + 0.1% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 480/crtc_commit:133: 0% user + 0.1% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 855/lmkd: 0% user + 0.1% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 1200/tombstoned: 0% user + 0% kernel / faults: 14 minor 42 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 31217/com.xiaomi.account:accountservice: 0.1% user + 0% kernel / faults: 850 minor
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 1/init: 0% user + 0% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 22/rcuop/1: 0% user + 0% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 38/rcuop/3: 0% user + 0.1% kernel
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 772/android.hardware.health@2.0-service: 0% user + 0% kernel / faults: 29 minor 4 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 1066/cameraserver: 0% user + 0% kernel / faults: 68 minor 2 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0% 1091/statsd: 0% user + 0% kernel / faults: 57 minor 4 major
04-14 18:30:05.259 E/ActivityManager( 1601): 0.1% 1438/ms
04-14 18:30:05.266 W/Looper ( 1601): Slow Looper ActivityManager: Long Msg: seq=13737 plan=18:29:45.215 late=0ms wall=20050ms running=492ms runnable=88ms io=102ms h=com.android.server.am.ActivityManagerService$MainHandler c=com.android.server.am.-$$Lambda$ActivityManagerService$suSj-_Gky16tELPffKx_qENL8g0
04-14 18:30:05.270 D/NfcService( 3673): Received android.intent.action.BATTERY_CHANGED
04-14 18:30:05.272 I/BatteryInfoReceiver( 4127): ACTION_BATTERY_CHANGED
可以看注释,这里面有一些关键信息,还有logcat在追查的时候,anr发生之前的15s内,应用发生了什么也是很重要的。
2.获取手机的trace.txt
直接运行 adb bug report 获取到一个压缩文件
打开里面的FS/data/anr 可以找到最近的anr文件
比如
anr_2021-04-14-18-29-45-686
里面内容包括:
----- pid 19377 at 2021-04-14 18:29:56 -----
Cmd line: com.cmft.cmuop.di
ABI: 'arm'
"Shutdown thread" sysTid=19377
#00 pc 000522b8 /apex/com.android.runtime/lib/bionic/libc.so (syscall+28) (BuildId: b1803e2c54cf63f48664b8839ccf313b)
#01 pc 000e48f1 /apex/com.android.runtime/lib/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+88) (BuildId: 42401a4bcc76d45f06b6e789cdff7a16)
#02 pc 003c328f /apex/com.android.runtime/lib/libart.so (art::ThreadList::WaitForOtherNonDaemonThreadsToExit()+102) (BuildId: 42401a4bcc76d45f06b6e789cdff7a16)
#03 pc 003c31ad /apex/com.android.runtime/lib/libart.so (art::ThreadList::ShutDown()+100) (BuildId: 42401a4bcc76d45f06b6e789cdff7a16)
#04 pc 00381a39 /apex/com.android.runtime/lib/libart.so (art::Runtime::~Runtime()+2032) (BuildId: 42401a4bcc76d45f06b6e789cdff7a16)
#05 pc 0029213b /apex/com.android.runtime/lib/libart.so (art::JII::DestroyJavaVM(_JavaVM*)+16) (BuildId: 42401a4bcc76d45f06b6e789cdff7a16)
#06 pc 0028ba13 /apex/com.android.runtime/lib/libart.so (art::(anonymous namespace)::CheckJII::DestroyJavaVM(_JavaVM*)+66) (BuildId: 42401a4bcc76d45f06b6e789cdff7a16)
#07 pc 00081d15 /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+660) (BuildId: fe441c97ee8bad7887fb238382b82786)
#08 pc 000023bd /system/bin/app_process32 (main+880) (BuildId: af6717380d7aac8078e97a46f3266f32)
#09 pc 000513a7 /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+66) (BuildId: b1803e2c54cf63f48664b8839ccf313b)
#10 pc 00002037 /system/bin/app_process32 (_start_main+46) (BuildId: af6717380d7aac8078e97a46f3266f32)
#11 pc 000b8db8 /apex/com.android.runtime/bin/linker (__dl___aeabi_uidivmod+12) (BuildId: affdb77e2875575acb3c04c831581b1a)
#12 pc 007fe78e [stack]
我们首要关注的就是mainThread的堆栈
"main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 flags=1 obj=0x76f643c8 self=0x7932e69c00
| sysTid=1601 nice=-10 cgrp=default sched=0/0 handle=0x79b8fa6ed0
| state=S schedstat=( 18627602214 5349007142 36121 ) utm=1310 stm=551 core=0 HZ=100
| stack=0x7fe1eb2000-0x7fe1eb4000 stackSize=8192KB
| held mutexes=
kernel: (couldn't read /proc/self/task/1601/stack)
native: #00 pc 00000000000c1368 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8)
native: #01 pc 0000000000018120 /system/lib64/libutils.so (android::Looper::pollInner(int)+144)
native: #02 pc 0000000000017ff0 /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+56)
native: #03 pc 000000000013eca8 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
at android.os.MessageQueue.nativePollOnce(Native method)
at android.os.MessageQueue.next(MessageQueue.java:336)
at android.os.Looper.loop(Looper.java:181)
at com.android.server.SystemServer.run(SystemServer.java:557)
at com.android.server.SystemServer.main(SystemServer.java:363)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:928)
一般情况下这里面会有主要线索 ,但是这里没有。
联想到这个anr是比较容易出现的,猜测有可能是其他崩溃导致的anr。
然后,查询anr发生前30s内的logcat,果然发现了不少异常。
在anr之前就有很多线程已经异常关闭了
最后找到了一个崩溃记录:
04-14 18:29:33.698 E/AndroidRuntime(19377): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.cmft.coco.meetinglib.bean.CallResult.getRoomId()' on a null object reference
04-14 18:29:33.704 I/Infors.DefaultPluginListener(19377): æ¥å¿ ->{"crash":{"processInfo":"com.cmft.cmuop.di","freeMemoryProportion":"3905M/5503M(70.97%)","occurTime":1618396173704,"crashType":"java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.cmft.coco.meetinglib.bean.CallResult.getRoomId()' on a null object reference","stackTrace":"java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.cmft.coco.meetinglib.bean.CallResult.getRoomId()' on a null object reference\n\tat com.cmft.coco.meetinglib.view.ChatViewHelper.onCallJoined(ChatViewHelper.java:314)\n\tat com.cmft.coco.meetinglib.view.activity.CallActivity.onCallJoined(CallActivity.java:152)\n\tat com.cmft.coco.meetinglib.view.CallMiniUi$5.run(CallMiniUi.java:354)\n\tat android.os.Handler.handleCallback(Handler.java:914)\n\tat android.os.Handler.dispat","crashId":"5d9502c7534b5dc8a40dc93c05562024"}}
04-14 18:29:35.780 E/CrashHandler(19377): [(CrashHandler.java:42):uncaughtException]java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.cmft.coco.meetinglib.bean.CallResult.getRoomId()' on a null object reference
04-14 18:29:35.784 D/MyCrash (19377): getName:java.lang.NullPointerException
对比发现 pid是一个进程的,最终确定anr是由这个崩溃导致的。
总结就是
:
分析logcat,traces日志,
确定anr类型,
查看main主线程堆栈
不断猜测验证。
下面是一些收集的文章:
Android ANR 问题第二弹------Input超时实战问题解析上
https://blog.csdn.net/abm1993/article/details/80497039
https://blog.csdn.net/weixin_43910395/article/details/103805842
https://blog.csdn.net/createchance/article/details/51954142
https://www.jianshu.com/p/18f16aba79dd?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
https://www.jianshu.com/p/ad1a84b6ec69
https://zhuanlan.zhihu.com/p/50107397