Android ANR

概述

从事Android开发的的肯定或多或少的遇到过,它的全称是Application Not Responding(应用程序无响应)。ANR的直观体现就是用户在操作APP的时候,比如按某个按钮,跳转某个页面,当卡顿超过一定时间时(一般为5秒)时就会出现ANR对话框。这是用户所不能忍受的,是一种很糟糕的体验。

产生的原因

一般有两种情况会产生ANR

  1. 当前的时间没有机会得到处理,例如UI线程正在响应另一个事件,当前事件由于某种原因被阻塞了。
  2. 当前事件正在处理,但是耗时很长,很长时间都处理不完。

ANR出现大致可以对应到Android中的四大组件中的三个(Activity/View,BroadcastReceiver和Service),View在5秒时间内还没有反应时就会ANR,BroadcastReceiver10秒无响应会ANR,Service20秒无响应就回ANR。

总的来说:主线程(View,BroadcastReceiver和Service都是工作在主线程的)阻塞或者处理较耗时的操作就可能产生ANR。

典型场景

  • 应用存在耗时操作,例如在UI线程中请求网络(在Android4.0之后,如果在UI线程中进行网络操作,会抛出NetworkOnMainThreadException异常),文件的读写等。
  • 主线程等待子线程释放某个锁,从而无法处理用户的操作。
  • 耗时的动画需要大量的计算工作,可能导致CPU负载过重。

如何出现ANR,如何定位?

  1. Log日志信息 查看ANR有关的信息,可以提供部分依据。
  2. 从Log中可以看到一句话
    I/zygote64: Wrote stack traces to '/data/anr/traces.txt'
    因此我们可以从traces.txt文件中得到一些有用的信息,我们可以通过终端Terminal中执行
    adb pull /data/anr/traces.txt 电脑目标路径
    将其拷贝到电脑中,让后就可以用文本编辑软件打开进行查看了。

如何快速查看?

通过搜索找到自己的包名,然后往后看at出现的地方,都这里就差不多找到了。如搜索包名后定位到

Cmd line: com.mhd.rxjava
Build fingerprint: 'samsung/dreamqltezc/dreamqltechn:8.0.0/R16NW/G9500ZCS3CSA2:user/release-keys'
ABI: 'arm64'
Build type: optimized
Zygote loaded classes=4815 post zygote classes=874
Intern table: 51639 strong; 326 weak
JNI: CheckJNI is on; globals=544 (plus 52 weak)
Libraries: /system/lib64/libandroid.so /system/lib64/libandroid_runtime.so /system/lib64/libcompiler_rt.so /system/lib64/libjavacrypto.so /system/lib64/libjnigraphics.so /system/lib64/libmdf.so /system/lib64/libmedia_jni.so /system/lib64/libqti_performance.so /system/lib64/libsoundpool.so /system/lib64/libwebviewchromium_loader.so libjavacore.so libopenjdk.so (12)
Heap: 73% free, 2MB/7MB; 32743 objects
Dumping cumulative Gc timings
Start Dumping histograms for 1 iterations for concurrent copying
ProcessMarkStack:	Sum: 3.970ms 99% C.I. 3.970ms-3.970ms Avg: 3.970ms Max: 3.970ms
VisitConcurrentRoots:	Sum: 1.748ms 99% C.I. 1.748ms-1.748ms Avg: 1.748ms Max: 1.748ms
ScanImmuneSpaces:	Sum: 759us 99% C.I. 759us-759us Avg: 759us Max: 759us
ThreadListFlip:	Sum: 651us 99% C.I. 651us-651us Avg: 651us Max: 651us
ClearFromSpace:	Sum: 539us 99% C.I. 539us-539us Avg: 539us Max: 539us
SweepSystemWeaks:	Sum: 246us 99% C.I. 246us-246us Avg: 246us Max: 246us
InitializePhase:	Sum: 245us 99% C.I. 245us-245us Avg: 245us Max: 245us
RecordFree:	Sum: 241us 99% C.I. 241us-241us Avg: 241us Max: 241us
GrayAllDirtyImmuneObjects:	Sum: 163us 99% C.I. 163us-163us Avg: 163us Max: 163us
FlipOtherThreads:	Sum: 85us 99% C.I. 85us-85us Avg: 85us Max: 85us
ClearRegionSpaceCards:	Sum: 73us 99% C.I. 73us-73us Avg: 73us Max: 73us
VisitNonThreadRoots:	Sum: 62us 99% C.I. 62us-62us Avg: 62us Max: 62us
EnqueueFinalizerReferences:	Sum: 43us 99% C.I. 43us-43us Avg: 43us Max: 43us
(Paused)ClearCards:	Sum: 25us 99% C.I. 250ns-7000ns Avg: 714ns Max: 7000ns
(Paused)FlipCallback:	Sum: 22us 99% C.I. 22us-22us Avg: 22us Max: 22us
MarkZygoteLargeObjects:	Sum: 21us 99% C.I. 21us-21us Avg: 21us Max: 21us
MarkStackAsLive:	Sum: 20us 99% C.I. 20us-20us Avg: 20us Max: 20us
EmptyRBMarkBitStack:	Sum: 13us 99% C.I. 13us-13us Avg: 13us Max: 13us
MarkingPhase:	Sum: 10us 99% C.I. 10us-10us Avg: 10us Max: 10us
ProcessReferences:	Sum: 9us 99% C.I. 1us-8us Avg: 4.500us Max: 8us
ForwardSoftReferences:	Sum: 4us 99% C.I. 4us-4us Avg: 4us Max: 4us
Sweep:	Sum: 3us 99% C.I. 3us-3us Avg: 3us Max: 3us
FlipThreadRoots:	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
concurrent copying paused:	Sum: 870us 99% C.I. 870us-870us Avg: 870us Max: 870us
concurrent copying total time: 9.020ms mean time: 9.020ms
concurrent copying freed: 7472 objects with total size 4MB
concurrent copying throughput: 830222/s / 501MB/s
Cumulative bytes moved 7638552
Cumulative objects moved 107890
Total time spent in GC: 9.020ms
Mean GC size throughput: 500MB/s
Mean GC object throughput: 828381 objects/s
Total number of allocations 40215
Total bytes allocated 6MB
Total bytes freed 4MB
Free memory 5MB
Free memory until GC 5MB
Free memory until OOME 253MB
Total memory 7MB
Max memory 256MB
Zygote space size 1156KB
Total mutator paused time: 870us
Total time waiting for GC to complete: 3.439us
Total GC count: 1
Total GC time: 9.020ms
Total blocking GC count: 0
Total blocking GC time: 0
Registered native bytes allocated: 4582439
/data/app/com.mhd.rxjava-cGueAbVzabNDPEf8xfk15Q==/oat/arm64/base.odex: quicken
Current JIT code cache size: 9KB
Current JIT data cache size: 8KB
Current JIT capacity: 64KB
Current number of JIT code cache entries: 20
Total number of JIT compilations: 20
Total number of JIT compilations for on stack replacement: 0
Total number of JIT code cache collections: 0
Memory used for stack maps: Avg: 114B Max: 360B Min: 24B
Memory used for compiled code: Avg: 474B Max: 2800B Min: 4B
Memory used for profiling info: Avg: 176B Max: 1544B Min: 32B
Start Dumping histograms for 20 iterations for JIT timings
Compiling:	Sum: 33.366ms 99% C.I. 0.188ms-13.060ms Avg: 1.668ms Max: 13.557ms
TrimMaps:	Sum: 940us 99% C.I. 9us-330us Avg: 47us Max: 339us
Done Dumping histograms
Memory used for compilation: Avg: 110KB Max: 385KB Min: 21KB
ProfileSaver total_bytes_written=0
ProfileSaver total_number_of_writes=0
ProfileSaver total_number_of_code_cache_queries=0
ProfileSaver total_number_of_skipped_writes=0
ProfileSaver total_number_of_failed_writes=0
ProfileSaver total_ms_of_sleep=5000
ProfileSaver total_ms_of_work=0
ProfileSaver max_number_profile_entries_cached=11
ProfileSaver total_number_of_hot_spikes=0
ProfileSaver total_number_of_wake_ups=0

suspend all histogram:	Sum: 141.530ms 99% C.I. 40us-7188.480us Avg: 620.745us Max: 8157us
DALVIK THREADS (14):
"Signal Catcher" daemon prio=5 tid=3 Runnable
  | group="system" sCount=0 dsCount=0 flags=0 obj=0x14f40088 self=0x7c104c5400
  | sysTid=17755 nice=0 cgrp=default sched=0/0 handle=0x7c056fe4f0
  | state=R schedstat=( 62595210 13061721 41 ) utm=2 stm=4 core=3 HZ=100
  | stack=0x7c05604000-0x7c05606000 stackSize=1005KB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 0000000000397fe4  /system/lib64/libart.so (_ZN3art15DumpNativeStackERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEEiP12BacktraceMapPKcPNS_9ArtMethodEPv+212)
  native: #01 pc 000000000045e474  /system/lib64/libart.so (_ZNK3art6Thread9DumpStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEEbP12BacktraceMapb+348)
  native: #02 pc 0000000000475c84  /system/lib64/libart.so (_ZN3art14DumpCheckpoint3RunEPNS_6ThreadE+880)
  native: #03 pc 000000000046df5c  /system/lib64/libart.so (_ZN3art10ThreadList13RunCheckpointEPNS_7ClosureES2_+480)
  native: #04 pc 000000000046d964  /system/lib64/libart.so (_ZN3art10ThreadList4DumpERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEEb+796)
  native: #05 pc 000000000046d504  /system/lib64/libart.so (_ZN3art10ThreadList14DumpForSigQuitERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE+920)
  native: #06 pc 00000000004429dc  /system/lib64/libart.so (_ZN3art7Runtime14DumpForSigQuitERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE+196)
  native: #07 pc 000000000044c314  /system/lib64/libart.so (_ZN3art13SignalCatcher13HandleSigQuitEv+1676)
  native: #08 pc 000000000044b14c  /system/lib64/libart.so (_ZN3art13SignalCatcher3RunEPv+396)
  native: #09 pc 000000000006814c  /system/lib64/libc.so (_ZL15__pthread_startPv+36)
  native: #10 pc 000000000001f664  /system/lib64/libc.so (__start_thread+68)
  (no managed stack frames)

"main" prio=5 tid=1 Sleeping
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x74c4c120 self=0x7c104c4a00
  | sysTid=17737 nice=-10 cgrp=default sched=0/0 handle=0x7c158b59c8
  | state=S schedstat=( 459672440 32520674 237 ) utm=41 stm=4 core=6 HZ=100
  | stack=0x7fc4f31000-0x7fc4f33000 stackSize=8MB
  | held mutexes=
  at java.lang.Thread.sleep(Native method)
  - sleeping on <0x07611fbd> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:373)
  - locked <0x07611fbd> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:314)
  at com.mhd.rxjava.MainActivity$5.run(MainActivity.java:79)
  at android.os.Handler.handleCallback(Handler.java:789)
  at android.os.Handler.dispatchMessage(Handler.java:98)
  at android.os.Looper.loop(Looper.java:164)
  at android.app.ActivityThread.main(ActivityThread.java:6938)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

向下一直看找到了at所在

在这里插入图片描述

查看源码
在这里插入图片描述
果然找到了问题所在。

ANR的避免和检测

1.使用StrictMode(严苛模式)用法简单自行百度。

2.使用三方库BlockCanary,BlockCanary是一个非侵入式的性能监控函数库,它的用法和LeakCanary类似,它主要用来检测应用主线程的卡顿。它的基本原理是利用主线程的消息队列的处理机制,通过对消息分发开始和结束的时间点来判断是否超过设定的时间,如果是,侧判定为主线程卡顿,集成比较简单,同LeakCanary。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值