赞
踩
ANR
(Application Not Responding
),程序长时间无响应。系统长时间无法处理某个操作,就会弹出ANR
对话框。
在Android
系统中,ActivityManagerService
(简称AMS
)和WindowManagerService
(简称WMS
)会检测APP
的响应时间,如果APP
在特定时间无法相应屏幕触摸或键盘输入,或者特定事件没有处理完毕,就会出现ANR
。
以下四个条件都可以造成ANR
发生:
InputDispatching Timeout
:5s
内无法响应屏幕触摸事件或键盘输入事件;Service Timeout
:前台服务20s
内,后台服务在200s
内没有执行完毕;BroadcastQueue Timeout
:在执行前台广播的onReceive
方法时10s
没有处理完成,后台为60s
;ContentProvider Timeout
:ContentProvider
的publish
在10s
内没进行完;造成以上ANR
的首要原因就是在主线程中做了太多的耗时操作,例如读写文件,访问数据库,网络请求等。因此,尽可能的避免在主线程中做耗时操作。
ANR
分析在MainActivity
中生成一个按钮跳转到ANRActivity
中,在后者的onCreate()
中主线程休眠20s
:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anr_test);
// 这是Android提供线程休眠函数,与Thread.sleep()最大的区别是
// 该使用该函数不会抛出InterruptedException异常。
SystemClock.sleep(20 * 1000);
}
在进入ANRActivity
后黑屏一段时间,再过几秒,弹出了ANR
异常:
日志打印:
2022-06-26 07:57:59.031 559-8280/system_process E/ActivityManager: ANR in com.example.kotlintest (com.example.kotlintest/.ui.MainActivity)
PID: 8213
Reason: Input dispatching timed out (3aa19cd com.example.kotlintest/com.example.kotlintest.ui.MainActivity (server) is not responding. Waited 5001ms for FocusEvent(hasFocus=false))
Parent: com.example.kotlintest/.ui.MainActivity
指令:adb shell ls /data/anr/
(查看日志文件) adb pull /data/anr/[文件名] ~/Desktop/
(导出日志)
adb bugreport ~/desktop/
(打包导出到桌面)
压缩包:
查看:
----- pid 8213 at 2022-06-26 07:57:57.303937000+0800 ----- Cmd line: com.example.kotlintest // 最新发生ANR的进程(包)名 "main" prio=5 tid=1 Sleeping // 产生ANR的原因Sleeping | group="main" sCount=1 ucsCount=0 flags=1 obj=0x71e37bb8 self=0x7b2e7961b380 | sysTid=8213 nice=-10 cgrp=top-app sched=0/0 handle=0x7b2fc66524f8 | state=S schedstat=( 1265272404 141474997 421 ) utm=66 stm=59 core=0 HZ=100 | stack=0x7ffc3fe30000-0x7ffc3fe32000 stackSize=8188KB | held mutexes= at java.lang.Thread.sleep(Native method) - sleeping on <0x0e6d0d57> (a java.lang.Object) at java.lang.Thread.sleep(Thread.java:451) - locked <0x0e6d0d57> (a java.lang.Object) at java.lang.Thread.sleep(Thread.java:356) at android.os.SystemClock.sleep(SystemClock.java:131) at com.example.kotlintest.ANRActivity.onCreate(ANRActivity.kt:11) // 产生ANR的包名以及具体行数 at android.app.Activity.performCreate(Activity.java:8051) at android.app.Activity.performCreate(Activity.java:8031) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
ANR
的原因及解决办法上面例子只是由于简单的主线程耗时操作造成的ANR
,造成ANR
的原因还有很多:
SharedPreference
;CPU
满负荷,I/O
阻塞,文件读写或数据库操作放在子线程异步操作;AndroidManifest.xml
文件<applicatiion>
中可以设置android:largeHeap = "true"
,以此增大APP
使用内存。不过不建议使用此法,从根本上防止内存泄漏,优化内存使用才是正道;ANR
:各大组件生命周期中也应避免耗时操作,注意BroadcastReciever.onRecieve()
、后台Service
和ContentProvider
也不要执行太长时间的任务;Android ANR:原理分析及解决办法
Mac android 导出anr文件
Mac 下导出ANR错误日志
ANR详解-Android
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。