聊聊 Android ANR 那点事儿

ANR 弹窗

ANR 在 Android开发中并不陌生,遇到 ANR 有时让我们很苦恼,自己平时也遇到过这样的问题,今天来聊聊 Android 中 ANR 那点事并记录在此,以防下次遇到我们就知道该如何分析了。

ANR定义

简单说下官方解释,ANR,Application Not Responding,即应用程序没有响应,Android 系统会向用户显示一个程序无响应对话框,用户可以选择等待或者强制关闭。

出现场景

  • 按键或触摸事件 5s 内无响应;
  • BroadcastReceiver 10s 内无法处理完成;
  • Service 在 20s 时间内无法处理完成;

发生 ANR 基本上都会出现无法响应对话框,除了一些后台程序的 ANR,造成 ANR 的原因很多,比如:

  • UI 主线程被其他操作阻塞;
  • 主线程存在耗时操作(本地 IO操作、网络访问、循环等);

如何分析

关于发生 ANR 截取的 log 和 trace 这里就不多说了

1、CPU 问题

  • 在 Monkeylog.log 文件中定位到 “anr in” 位置,查看 cpu usage ,total 占用,如发现接近100%,暂时判断为 cpu 问题。
  • 然后在 logcat.log 文件中定位到 “not responding” 发生时间,并截取
    cpuinfo.log 中时间点前后 5s 的 log,然后计算 CPU 占中,看哪个进程用的多,在酌情分析模块的 CPU 占中。

2、GC 问题

  • 定位到 logcat.log 文件中 “not responding” 发生时间点;

  • 去查看发生 ANR 时间点对应的 trace 文件,定位到应用报名,若Dalvik Thread主线程显示“SUSPENDED”,则为内存问题;

  • 截取 ANR 发生时间点前 5s 的 log,分析 “dalvikvm” 打印的 Paused GC 耗时,如果过多则定位为 GC 问题,需要查看这 5s 件发生了哪些耗时的操作。

注意:发生 GC 的进程 id 需要和当前发生 ANR 的线程 id 的要一致

如何避免

  • 合理使用 UI 主线程,耗时操作放入其他线程工作;
  • 合理使用 Handler 来处理其他线程请求;
  • 合理使用并遵循 Android 生命周期, 避免在 onCreate() and onResume() 做过多的事情;
  • 使用一些架构形成规范来避免内存等问题,例如:MVP、RxJava;
  • 经常使用工具来检查内存问题,例如:MAT、TraceView、AS 自带等工具;
  • 避免加载大图片引起内存不足导致 ANR;
  • 避免内存泄露引起的 ANR。

比如官方例子中:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     // Do the long-running work in here
     // 耗时操作放这里
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     // This is called each time you call publishProgress()
     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     // This is called when doInBackground() is finished
      // 耗时操作完成后 Post 到 UI 主线程
     protected void onPostExecute(Long result) {
         showNotification("Downloaded " + result + " bytes");
     }
 }

友好处理

一般情况下, 超过100至200毫秒用户会感知程序有些缓慢。因此,可以做一些比较友好的 UI 提示页面,比如:ProgressBar,来表明当前正在处理,使得用户不会去一直点击页面,减少输入即可能减少 ANR 出现几率,因为按键5s不响应是会出现 ANR 的。

可以使用性能工具来优化我们的 App,如 SystraceTraceview

关于内存泄露分析可以查看之前总结的 Android 内存泄漏工具使用分析
如果有错,欢迎大家指正!

参考

官方文档
Android 内存泄漏工具使用分析
Keeping Your App Responsive

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值