Android轻量级APM性能监测方案

本文探讨了Android应用性能监测的关键指标,包括启动耗时、FPS、内存泄露、流量和电量监测。建议自研轻量级APM方案,避免线上风险。通过ContentProvider记录冷启动时间,利用Activity Lifecycle监测页面启动和FPS,使用WeakHashMap检测内存泄露,以及跟踪流量消耗。同时,提出了对CPU使用率和电量监测的思考。
摘要由CSDN通过智能技术生成

App性能如何量化

如何衡量一个APP性能好坏?直观感受就是:启动快、流畅、不闪退、耗电少等感官指标,反应到技术层面包装下就是:

  1. FPS(帧率)、
  2. 界面渲染速度、
  3. Crash率、
  4. 网络、
  5. CPU使用率、
  6. 电量损耗速度

等,一般挑其中几个关键指标作为APP质量的标尺。目前也有多种开源APM监控方案,但大部分偏向离线检测,对于线上监测而言显得太重,可能会适得其反,方案简单对比如下:

SDK

现状与问题

是否推荐直接线上使用

腾讯matrix

功能全,但是重,而且运行测试期间经常Crash

腾讯GT

2018年之后没更新,关注度低,本身功能挺多,也挺重性价比还不如matrix

网易Emmagee

2018年之后没更新,几乎没有关注度,重

听云App

适合监测网络跟启动,场景受限

还有其他多种APM检测工具,功能复杂多样,但其实很多指标并不是特别重要,实现越复杂,线上风险越大,因此,并不建议直接使用。而且,分析多家APP的实现原理,其核心思路基本相同,且门槛也并不是特别高,建议自研一套,在灵活性、安全性上更有保障,更容易做到轻量级。本文主旨就是围绕几个关键指标:FPS、内存(内存泄漏)、界面启动、流量等,实现轻量级的线上监测。

核心性能指标拆解

  • 稳定性:Crash统计

Crash统计与聚合有比较通用的策略,比如Firebase、Bugly等,不在本文讨论范围

  • 网络请求

每个APP的网络请求一般都存在统一的Hook点,门槛很低,且各家请求协议与SDK有别,很难实现统一的网络请求监测,其次,想要真正定位网络请求问题,可能牵扯整个请求的链路,更适合做一套网络全链路监控APM,也不在讨论范围。

  • 冷启动时间及各个Activity页面启动时间 (存在统一方案)
  • 页面FPS、卡顿、ANR (存在统一方案)
  • 内存统计及内存泄露侦测 (存在统一方案)
  • 流量消耗 (存在统一方案)
  • 电量 (存在统一方案)
  • CPU使用率(CPU):还没想好咋么用,7.0之后实现机制也变了,先不考虑

线上监测的重点就聚焦后面几个,下面逐个拆解如何实现。

启动耗时

直观上说界面启动就是:从点击一个图标到看到下一个界面首帧,如果这个过程耗时较长,用户会会感受到顿挫,影响体验。从场景上说,启动耗时间简单分两种:

  • 冷启动耗时:在APP未启动的情况从,从点击桌面icon 到看到闪屏Activity的首帧(非默认背景)
  • 界面启动耗:APP启动后,从上一个界面pause,到下一个界面首帧可见,

本文粒度较粗,主要聚焦Activity,这里有个比较核心的时机:Activity首帧可见点,这个点究竟在什么时候?经分析测试发现,不同版本表现不一,在Android 10 之前这个点与onWindowFocusChanged回调点基本吻合,在Android 10 之后,系统做了优化,将首帧可见的时机提前到onWindowFocusChanged之前,可以简单看做onResume(或者onAttachedToWindow)之后,对于一开始点击icon的点,可以约等于APP进程启动的点,拿到了上面两个时间点,就可以得到冷启动耗时。

APP进程启动的点可以通过加载一个空的ContentProvider来记录,因为ContentProvider的加载时机比较靠前,早于Application的onCreate之前,相对更准确一点,很多SDK的初始也采用这种方式,实现如下:

public class LauncherHelpProvider extends ContentProvider {

    // 用来记录启动时间
    public static long sStartUpTimeStamp = SystemClock.uptimeMillis();
    ...
    
    }

这样就得到了冷启动的开始时间,如何得到第一个Activity界面可见的时间呢?比较简单的做法是在SplashActivity中进行打点,对于Android 10 以前的,可以在onWindowFocusChanged中打点,在Android 10以后,可以在onResume之后进行打点。不过,做SDK需要减少对业务的入侵,可以借助Applicattion监听Activity Lifecycle无入侵获取这个时间点。对于Android 10之前系统, 可以利用ViewTreeObserve监听nWindowFocusChange回调,达到无入侵获取onWindowFocusChanged调用点,示意代码如下

   application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
       ....
       @Override
    public void onActivityResumed(@NonNull final Activity activity) {
        super.onActivityResumed(activity);
        launcherFlag |= resumeFlag;
        
          <!--添加onWindowFocusChanged 监听-->
            activity.getWindow().getDecorView().getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {
            <!--onWindowFocusChanged回调-->
            @Override
            public void onWindowFocusChanged(boolean b) {
                if (b && (launcherFlag ^ startFlag) == 0) {
                   <!--判断是不是首个Activity-->
                    final
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值