IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 性能优化--卡顿,ANR ,方法耗时监测 -> 正文阅读

[移动开发]Android 性能优化--卡顿,ANR ,方法耗时监测

常见anr

input,点击事件:5秒;
contentprovider:10秒;
Broadcast:前台10秒,后台60秒;
服务 service:前台20秒,后台200秒

原理

埋炸弹和拆炸弹

当启动service的时候,会调用

scheduleCreateService方法创建service
 app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);

在创建过程中,利用handler发送延时消息,预埋炸弹

mAm.mHandler.sendMessageDelayed(msg, proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);

如果在延时时间内完成对应的操作,则handler会移除掉刚才的延时消息,拆除炸弹

mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);

这种利用handler的延迟消息,埋炸弹和拆炸弹的设计思想,可以在日常开发中使用和借鉴。如watchdog就是使用该原理实现的

如果在规定的时间内炸弹没有被拆除,则会执行系统的appNotResponding方法,搜集当前堆栈信息,打印到控制台和写入trace文件中

final void appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, boolean aboveSystem, final String annotation){

}

除了input事件外,其他的anr类型都是采用的这种装炸弹和拆炸弹的方式,input采用的是接受下一个input事件时再去检查是否anr的方案

核心流转代码--Loop.loop()函数

public static void loop() {
      for (;;) {
            Message msg = queue.next(); 
            ...        
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }
            ...
     
            msg.target.dispatchMessage(msg);
            ...
            
            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }
       }
       ...
}

anr从代码流程和监控上来说主要有两个收口点,分别是Message msg = queue.next()函数执行过长,或者是msg.target.dispatchMessage(msg);具体的消息的执行函数时间过长,所以从监控上只需要监控这两个点就可以。

监控方案

BlockCanary,watchDog 方案

网上很多方案如BlockCanary,watchDog是通过监控 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); 来计算是否耗时,从而打印出堆栈来定位卡断的,但是这个时候定位到的卡顿信息并不准确,因为此时函数已经执行完毕,并不能准确反映卡顿现场的具体堆栈信息。在实际操作中需要密集dumo堆栈才能获取准确信息。但是密集dump堆栈带来的卡顿和大hprof文件传输,使得结果适得其反

字节码插桩

利用Gradle Plugin和ASM,在方法的开始和结束前后各加入一个统计耗时的方法,然后定义好阈值,超过阈值则打印出对应的堆栈。这个时候获取到的堆栈是准确的,但是会引起方法数暴增,因此要做好策略和字节码插桩的范围。

线上监控方案

无论是字节码插桩还是BlockCanary或watchDog ,都不宜全量带到线上正式包中。实际操作中可以采用二者相互结合的方式。

如debug和灰度期间可以是用字节码插桩监控耗时和anr的包,同时监控logging.println("<<<<< Finished to " + msg.target + " " + msg.callback)的代码在有开关和策略的配合下带到线上,根据具体问题和需求灵活关闭和开启。做到既可以解决问题,同时又不影响性能

BlockCanary和watchdog的改进

网上的开源库一般具有普遍适用的特点,但是我们要根据我们项目自身的特点和需求进行改造,或者参考其源码和设计进行自己编写。

如BlockCanary,我们可以自定义监控logging.println("<<<<< Finished to " + msg.target + " " + msg.callback),在监测到卡顿时候增加自己业务特殊的逻辑,同时适配开关和动态降级策略。

watchdog基于埋炸弹和拆炸弹思想实现,每5秒计算一下是否卡顿,因此容易造成5秒的误差。我们可以将间隔时间改造成1秒,累计连续监测到5次标记位没被改变,则可以认为是发生了卡顿。这样既减少误差,同时也不会影响性能。

**除以上知识点之外,还有大厂面试讲解和android开发视频可以前往观看:[https://www.bilibili.com/video/BV12b4y1a7Fd/

如果你觉得有所收获,可以点赞收藏关注哦,接下来,我将继续对Android的相关知识进行分析和分享,可以继续关注哦,要是真正想学习android开发这块的,或者在这方面工作的朋友我免费分享给你,当然也希望大家都能多多支持我,你们的点赞就是我的动力,谢谢!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:23:57  更:2021-10-09 16:24:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:29:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码