Android卡顿优化 | ANR分析与实战(附ANR-WatchDog源码分析及实战、与AndroidPerformanceMonitor的区别)

简介: Android卡顿优化 | ANR分析与实战(附ANR-WatchDog源码分析及实战、与AndroidPerformanceMonitor的区别)

本文要点

  • ANR概述
  • 发生ANR后Android系统的执行流程
  • ANR-WatchDog原理与实战
  • ANR的传统解决套路
  • ANR模拟实战
  • 线上ANR监控方案【ANR-WatchDog原理分析】
  • ANR-WatchDog实战
  • ANR-WatchDog总结
  • ANR-WatchDog与AndroidPerformanceMonitor的区别

项目GitHub

ANR概述

  • KeyDispatchTimeout,5s

即按键或者触摸事件,在特定的时间(一般5s)之内没有响应;

  • BroadcastTimeout,前台10s,后台60s

BroadReceiver 在特定的时间(一般前台10s,后台60s)之内没有响应完成;

  • ServiceTimeout,前台20s,后台200s

Service 在特定的时间(一般前台20s,后台200s)之内没有处理完成;

发生ANR后Android系统的执行流程

  • APP发生ANR
  • 进程接收异常终止信号,开始写入进程ANR信息(当时场景,包含当前线程所有堆栈信息、CPU/IO的使用情况等);
  • 弹出ANR提示框,提示用户关闭APP或者继续等待;(不同ROM表现不同,有的手机厂商会去掉这个提示框)

ANR的传统解决套路

  • 【线下】在AS的Terminal中,使用

adb pull data/anr/traces.txt 要存储在本地的路径
导出上面提到的ANR现场信息文件
导出来后,便可对文件内容进行详细分析:从CPU、IO、锁冲突等原因思考;

ANR模拟实战

  • 模拟ANR原因:锁冲突;

更改代码:运行程序,等到程序ANR或崩溃,
在Terminal使用刚刚提到的命令,导出ANR的信息文件:生成文件:打开文件,可以找到原因:上次的BlockCanary同样捕捉到原因:

线下套路其实就是在APP发生ANR时,
导出信息文件,
查看文件,结合代码进行分析;

线上ANR监控方案

  • 通过FileOberver监控上述的ANR信息文件的变化,

如果这个文件发生了变化,那就说明发生了ANR,
那便可以把它上报到服务器,进行详细的分析;
【高版本需注意权限问题】

ANRWatchDog中,用一个绑定了主线程Looper的Handler,
去处理_ticker【一个Runnable任务单元】;
任务单元对一些值进行了处理,如_tick_reported_tick在初始为ANRWatchDog的全局变量时,被赋值为0;^^^^^^^^^^^^^^^^^
ANRWatchDogrun()中,
首先被利用去判定_ticker被post没有(因为一开始就_tick为0的话说明_tick还没被post),
没有便将_tick=加上卡顿周期,之后post了_ticker
此时_tick不为0!!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ticker中的run(),再一次将_tick置零;^^^^^^^^^^^^^^^^^^^^^^^^^^
所以只要_ticker不被处理,其run()便不会执行,
_tick就不会被置零,
由此根据_tick的值可以判断_ticker是否被处理了;
_tick重新归零则主线程处理了_ticker
_tick不为零则判定主线程卡顿,它没处理_tick!!!!!!!!

ANRWatchDogrun()中,
用刚说的主线程Handler,post了_ticker这个任务,
然后自己sleep一段时间【即一个卡顿周期,稍后细说】,
如果sleep结束之后,如果_tick != 0 && !_reported
则说明主线程还没有处理_tickerrun()
没有处理_ticker这个任务单元,
那便认为主线程发生了卡顿【如源码注释所示】:!!!!!!
确定发生了卡顿,就开始封装一个ANRError,进行后续处理了:另外补充一下,
ANRWatchDog提供了两个重载的构造器,
提供给开发者对卡顿判定周期进行设置,开发者不设置则使用默认配置
【跟BlockCanary同一个德行】接着仔细看ANRError的构造流程这里是有两种构造方式New()NewMainOnly(),其最终处理都差不多,
就是通过mainLooper拿到主线程,
再通过主线程拿到现场的堆栈信息
最后返回构造好的ANRError实例:拿到ANRError实例之后,
通过_anrListener.onAppNotResponding(error);回调机制处理ANRError实例;
回调机制就妙啊!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
刚刚的_anrListener.onAppNotResponding(error);只是一个应用层上的调用;
onAppNotResponding()的实现方式暴露给开发者了,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在外部可以通过setANRListener()自己定制包含不同处理方式的ANRListener
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^开发者不定制,则使用框架自带的默认处理方式呗:
处理方式简单粗暴哈,直接把ANRError丢出去,
这样APP就直接崩溃了:ANRError乃是Error的子类:**

ANR-WatchDog实战

  • 引入依赖
  • 初始化ANR-WatchDog:
  • **还是上面那个项目,手动阻塞60s,

运行程序,
程序会5s后崩溃【5s是默认周期时间,崩溃操作见上面源码分析】
logcat定位关键字fatal,可以看到ANRError打印的信息,
信息中包括了崩溃现场所有线程堆栈信息
以及显示bug代码的位置;**

**优化:
当然默认的APP崩溃处理法并不妥当,
影响用户体验,
实际开发中,
我们可以自己定义 ANRListener,自定义处理方式【上面说过了】,
把堆栈信息上报给服务器就是了!!!!**

总结

  • 非浸入式
  • 弥补高版本无权限问题

与AndroidPerformanceMonitor的区别

  • **AndroidPerformanceMonitor:

原理是基于Handler-Message机制,
监控主线程每一个Message的执行,
在每一个Message的分发执行前后,进行信息处理;
(不足:
一般没有阻塞的情况下,
每一个Message的执行时间是非常短暂的,
达不到ANR的级别;
而且InputEvent在queue.next中block,不会继续执行dispatchMessage,
而是从native回调给InputEventReceiver.dispatchInputEvent处理分发,
所以BlockCanary也就无法监控到这类ANR)**

  • **ANR-WatchDog:

不管主线程是怎么执行的,
只管最后的结果,
我sleep一个周期之后,就要看我_tick值有没有被修改,
没被修改就是ANR!**

  • **AndroidPerformanceMonitor适合全程监控卡顿,

ANR-WatchDog适合补充ANR监控;
两者可以相辅相成,结合使用!**





参考:

  • 慕课网

推荐:

相关文章
|
29天前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
115 4
|
1月前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
21天前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
27 8
|
25天前
|
安全 Android开发 数据安全/隐私保护
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
32 1
|
1月前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
Java Android开发 异构计算
|
1月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
17天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
1月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
17天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
41 14