ANR:Application Not Responding

QuibblerQuibbler 2020-07-27 约 7 分钟 2332 次阅读

ANR:Application Not Responding

使用Android手机有时候会遇到系统弹框“应用程序无响应”,这是因为APP在前台或者后台主线程中执行的时间太长,没有响应用户的操作。

1、ANR条件

系统ActivityManager和WindowManager会监控应用,如下三种条件下会产生ANR:

①Activity:前台在5s内无法响应输入事件(触摸、按键);定义在:ActivityTaskManagerService 

// How long we wait until we timeout on key dispatching.
    public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
    
    // How long we wait until we timeout on key dispatching during instrumentation.
    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
    
    // How long we permit background activity starts after an activity in the process started or finished.
    static final long ACTIVITY_BG_START_GRACE_PERIOD_MS = 10 * 1000;

②BroadcastReceiver:前台广播10s,后台广播60s无法响应;定义在:ActivityManagerService 

// How long we allow a receiver to run before giving up on it.
    static final int BROADCAST_FG_TIMEOUT = 10*1000;
    
    static final int BROADCAST_BG_TIMEOUT = 60*1000;

③Service:前台服务20s,后台服务200s未响应;定义在:ActiveServices 

// How long we wait for a service to finish executing.
    static final int SERVICE_TIMEOUT = 20*1000;
    
    // How long we wait for a service to finish executing.
    static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
    
    // How long the startForegroundService() grace period is to get around to
    // calling startForeground() before we ANR + stop it.
    static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;

2、ANR分析

当应用出现ANR,这个时候就该好好通过trance分析分析到底应用程序主线程哪里进行了耗时操作,需要移到子线程中处理。打开开发者选项中的ANR开关,直观的看到系统提示ANR弹框。

2.1、示例

想造一个ANR,很简单,在前台主线程Sleep超过5s即可。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        try {
            Thread.sleep(500000);
        } catch (Exception e) {
            Log.d(TAG, e.toString());
        }
    }

运行打开应用直接黑屏,按Home键都没有作用。如果手机上遇到这种应用建议直接卸载。

2.2、日志分析

应用程序产生ANR都会在/data/anr/目录下生成一个日志,比如:/data/anr/anr_2020-07-27-23-06-18-920。用adb命令pull出来分析,当然还有其它途径获取相关日志。(用的华为手机演示,竟然要root才能把anr日志pull出来)

adb pull data/anr .

2.3、trace分析

拿不到日志或者通过日志还需要进一步分析,产生ANR的原因。使用DDMS工具,抓取trace获取执行的时序图:


可以看到main一直卡住,直到最后才能执行,UI线程超时后就会发生ANR,查看耗时的方法:


3、避免ANR

避免ANR:不要在主线程执行耗时操作,主线程只执行UI操作。其它所有的数据、网络、文件读写都在子线程中(最好用线程池统一管理线程)。

①主线程只操作UI

②耗时(I/O、网络)操作全部放到子线程

③频繁的GC也会导致ANR,需要优化内存

④即将发生OOM前也会可能产生ANR,因为频繁的GC

推荐资料:

        如何分析ANR问题?

        转如何分析解决Android ANR

        ANR分析思路简析

        Android应用ANR分析

        ANR源码分析之Broadcast Timeout

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w