Android性能优化——启动优化

App 的启动速度是用户的第一体验,互联网中有一个八秒定律,如果用户等待八秒App 还没打开,70%的用户都会停止等待

 一、启动分类

官方 App startup time 

  • 冷启动

         耗时最多,衡量标准

  • 热启动

         最快。  后台~前台

  • 温启动

         较快。只会重走activity的生命周期,不会走进程的创建以及Application的创建和生命周期

冷启动流程

  1. 用户点击 
  2. 触发IPC 操作
  3. Process.start 进程创建
  4. ActivityThread 是每个单独进程的入口,会有一个main方法,进行消息循环的创建以及handler的创建
  5. bindApplication 通过反射创建Application 以及调用application的生命周期
  6. Activity 的生命周期 LifeCycle 
  7. ViewRootImpl 开始真正的界面绘制

冷启动之前(这个过程无法干预)

  • 启动App 
  • 加载空白Window 
  • 创建进程

随后任务

  • 创建Application 
  • 启动主线程
  • 创建MainActivity 
  • 加载布局
  • 布置屏幕
  • 首帧绘制

优化方向
        Application 和Activity 的生命周期

二、启动时间的测量方式

adb 命令方式

        adb shell am start -W packagename/首屏Activity 

    特点:

  • 线下使用方便,不能带到线上
  • 非严谨,精确时间

手动打点方式
        启动时埋点,启动结束埋点,二者差值
     特点:       

         精确,可带到线上,推荐使用

     避开误区

  • 启动时间开始的位置在application 中的attachBaseContext 
  • 启动时间结束的位置采用采用Feed 第一条展示
  • addOnDrawListener 要求Api 16

ThisTime 最后一个Activity启动耗时
TotalTime 所有Activity 的启动耗时
WaitTime AMS启动Activity 的总耗时

三、启动优化使用到的工具

 traceview,systrace 

  • 两种工具互相补充
  • 正确认识工具及不同场景选择合适的工具

traceview

  • 优点
    •  图形的形式,展示代码执行的时间,调用栈信息等
    • 信息全面,包含所有线程信息
  •  使用方式

      Debug.startMethodTracing(“文件名”);默认8M大小,如果想要更大,传参bufferSize 
      Debug.stopMethodTracing() 结束
      就会生成一个文件,位置在sd卡 :Android/data/packagename/files

在Android Studio 右边有一个Devices File Explorer 可以很方便的打开手机系统的文件
添加开启和结束的代码后,然后运行,在存储的位置下,刷新,会生成一个设置的文件名.trace 文件

  • 如何分析
    • 左上是通过代码精确指定的时间范围,左下角有个时间搓,不是特别重要
    • 左下是线程信息,可以看到线程的总数,也可以看到每个线程在具体的时间做了哪些事 

右边有四个Tab 

  • Top Down

total:总时间

self :

children:

举例:调用了A函数,整体时间是total,在A函数中调用了一行代码,然后执行B函数,它的selfTime是执行了一行代码的时间,childrenTime就是B函数执行的时间,selfTime和childrenTime之和一定等于totalTime

函数的调用列表,点击相应的jump to souse 可以跳入详细的代码中

ThreadTime 一定会变少,CPU执行的时间
Wall Clock Time 代码发生在这个线程上,真正执行的时间

  • Call chat 

每一行显示的是函数调用的时间段,垂直方法被调用着
系统Api 调用颜色是橙色
应用自身的函数调用是绿色
第三方Api 调用是蓝色

  • Flame chat 火焰图

倒置的调用图表,会收集相同的调用顺序

  • Bottom up

谁调用了我,和Top down 是相反的

总结:
        运行时开销严重,整体都会变慢这个工具太强大了,会抓去所有线程的所有执行函数以及顺序
        可能会带偏优化方向
        traceview 和cpu profiler 
                traceview 的好处可以在代码中进行埋点,用cpu profiler 进行分析
                单纯的用cpu profiler 来抓取精确的启动位置,几乎不可能

 systrace

结合Android内核的数据生成html 报告
Python脚本

  • 使用方式

• python systrace.py -t 10 [other-options] [categories]

  • 官方文档:

https://developer.android.com/studio/command-line/systrace#command_options

  • 使用案例

python /Users/Liuzhao.Future/Library/Android/sdk/platform-tools/ systrace/systrace.py -b 32768 -t 5 -a com.optimize.performance -o performance. html sched gf view wm am app

  • 代码中使用

开启:TraceCompat.beginSection(“apponCreate ”)
结束:TraceCompat.endSection 

  • 分析html 文件

CPU核数跟不同手机是有关系的,有些手机厂商8个核都给你,有的手机8核,但是只给你使用4核

  • 总结:
    • 轻量级,开销小,埋了哪一点就去做哪一点
    • 直观反映CPU利用率

cpuTime 和 wallTime

  • wallTime 是代码执行的时间
  • cpuTime 是代码消耗CPU的时间(重点指标)

举例:为什么两者会不一样
        锁冲突,比如一个线程执行需要获取锁A,但是锁A被其他线程持有,没有得到释放,而这个线程是一个轻量级的,只占用了cpu 一点时间,所以这个时候cpuTime 就会很短,而wallTime 很长

四、如何优雅的获取CPU耗时

需要知道具体哪个方法占用了大量时间

  • 常规方式:手动埋点
    • 侵入性强
    • 工作量大
  • AOP方式:Aspect Oriented Programming ,面向切面编程
    • 针对同一类问题的统一处理
    • 无侵入添加代码

Aspect使用

  • classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'
  • implementation 'org.aspectjaspectjrt:1.8.+'
  • apply plugin: 'android-aspectix'

介绍

  • Join Points
    • 程序运行时的执行点 ,可以作为切面的地方
    • 函数调用、执行
    • 获取、设置变量
    • 类初始化
  • PointCut
    • 带条件的JoinPoints
  • Advice
    • 一种Hook,要插入代码的位置
    • Before : PointCut之前执行
    • After :PointCut之后执行
    • Around: Pointcut之前、之后分别执行
  • 语法简介
    //Before:Advice,具体插入位置
    //execution :处理Join Point的类型
    //(* android.app.Activity.on**(.)):匹配规则
    @Before("execution(* android.app.Activity.on** (.))") 
    public void onActivityCalled (JoinPoint joinPoint) thr
    ows Throwable {
        ……
    }
  • 使用案例
@Aspect
public class Performanceaop{

    Around("call(*com.optimize.performance.PerformanceApp.**(..))") 
    public void getTime(ProceedingJoinPointjoinPoint){
        Signature signature=joinPoint.getSignature(); 
        String name=signaturetoShortString(); 
        long time=System.currentTimeMillis(); 
        try {
            joinPoint.proceed();
        } catch(Throwable throwable){
            throwable.printStackTrace();
        }
        LogUtils.i(msg:name+" cost "+(System.currentTimeMillis() - time));
    }
}
  • 优点
    • 无侵入性
    • 修改方便

五、异步优化

  • 常规异步优化:使用线程池进行异步优化
  • 启动器(异步启动优化的最优解)

常规异步方式

常规异步方式需要注意点:

  • 并不是所有的代码都可以直接异步
  1. 不符合异步要求:有的任务必须在主线程中执行
  2. 需要在某阶段完成,在splash界面就要用到异步任务,在执行界面的时候,异步任务还没完成某一些代码必须在某一个阶段完成,解决方案:CountDownLatch 相当于自己加了个锁
  3. 区分CPU 密集型还是IO密集型任务

常规异步方案痛点:

  • 代码不够优雅
  • 场景不好处理(依赖关系),在特定的时间内结束某个任务
  • 维护成本高

启动器方式

核心思想:
     充分利用CPU 多核,自动梳理任务顺序
启动器流程:

  • 代码Task化,启动逻辑抽象为Task 
  • 根据所有任务的依赖关系生成一个有向无环图
  • 多线程按照排序后的优先级依次执行

六、延迟初始化

  • 常规方案:handler.postDelay 
  • 更优方案:对延迟任务进行分批初始化

常规方案的问题:

  • 时机不便控制
  • 导致Feed卡顿

更优方案的优点:利用了IdleHandler特性,空闲执行

  • 执行时间明确
  • 缓解Feed卡顿

七、总结:启动优化总方针

  • 异步 ,延迟,懒加载
  • 技术和业务相结合

八、注意事项

  • 收敛启动代码修改权限
  • 结合Ci修改启动代码需要Review 或 通知

九、其它方案

  • 提前加载SharedPreferences 

        在multidex之前加载,充分利用此阶段CPU 
        覆写getApplicationContext返回this

  • 启动阶段不启动子进程

        子进程会共享CPU资源,导致主进程CPU 紧张
         注意启动顺序,App onCreate 之前是ContentProvider 

  • 类加载优化,提前异步类加载
  • 启动阶段抑制GC 
  • CPU锁频

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/39543.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据中心水浸事件,该如何找回安全?

数据中心是现代企业和组织中不可或缺的基础设施,承载着大量的敏感数据和关键业务运作。然而,水浸事件可能成为数据中心的巨大威胁,可能导致设备故障、数据丢失以及业务中断,给组织带来严重的损失和风险。 因此,为了保护…

linux之Ubuntu系列(八)用户管理 修改文件权限

修改文件权限 chown 修改拥有者 -R:递归更改文件属组,就是在更改某个目录文件的属组时,如果加上-R的参数,那么该目录下的所有文件的属组都会更改。 修改 文件|目录 的拥有者 sudo chown [-R] 用户名 文件名|目录 更改文件属主&…

pytest 参数化进阶

目录 前言: 语法 参数化误区 实践 简要回顾 前言: pytest是一个功能强大的Python测试框架,它提供了参数化功能,可以帮助简化测试用例的编写和管理。 语法 本文就赶紧聊一聊 pytest 的参数化是怎么玩的。 pytest.mark.par…

⛳ Java数组

Java数组的目录 ⛳ Java数组🎨 一,一维数组👣 1.1,概念📢 1.2,基本用法1,语法格式2,代码 💻 1.3,内存结构📝 1.4,练习 🎁 …

DB-Engines排名公布 GBASE南大通用入围国产数据库TOP 3

什么是DB-Engines排名? DB-Engines排名是数据库领域的流行度榜单,它对全球范围内的419款数据库(截至2023年7月)进行排名,每月更新一次,排名越靠前,则表示越流行。在很多技术选型的场合&#xf…

亚信科技荣任「DBL电信行业工作组」副组长单位,AntDB数据库连年入选《中国数据库产品图谱》

日前,“2023可信数据库发展大会”在京圆满召开。亚信科技凭借自研的电信级核心交易数据库AntDB在通信行业15年的技术积累和行业贡献,成功当选为数据库应用创新实验室(DBL)电信行业工作组副组长单位。AntDB数据库连续两年入选《全球…

Stable Diffusion - 编辑生成 (OpenPose Editor) 相同人物姿势的图像

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/131818943 OpenPose Editor 是 Stable Diffusion 的扩展插件,可以自定义人物的姿势和表情,以及生成深度、法线和边缘图等信…

学会在重装系统前如何备份软件,再也不怕失去珍贵的应用!

​Windows系统是电脑的重要组成部分,它不仅提供了友好的用户界面,还承担着许多关键的功能和任务,为我们提供了一个稳定、安全和效率的工作环境,使我们能够充分发挥电脑的潜力,优化工作效率和生活品质。 随着系统使…

浅谈测试工程化 - 以并发自动化框架为例

目录 前言 测试工程化 一、测试需求分析 二、测试设计 三、测试实现和落地 四、测试维护 扩展 前言 测试工程化是指将软件测试过程中的各个环节进行自动化和标准化,以提高测试效率、质量和可持续性。在测试工程化中,使用并发自动化框架是一个重要…

kotlin中使用Room数据库(包含升降级崩溃处理)

目录 1.导入依赖库 2.数据实体类 3.数据访问对象 (DAO) 4.数据库类 5.调用DAO里面的“增、删、改、查”方法 6.数据库升降级处理 升级(保存数据库历史数据): 升级(不保存数据库历史数据): 降级&…

NUXT3学习笔记2

1、配置Ant design Vue (两个安装方式随便选一种,yarn会安装的更快) npm i ant-design-vue --save yarn add ant-design-vue 2、使⽤的 Vite,你可以使⽤ unplugin-vue-components 来进⾏按需加载。 yarn add unplugin-vue-components --save 在nuxt.…

【iOS】探索ARC的实现

ARC ARC在编译期和运行期做了什么?编译期:运行期:block 是如何在 ARC 中工作的? ARC的实现分析__strong自己生成并持有storeStrongSideTable散列表objc_retainobjc_releasesidetable_releaseretainCount非自己生成并持有 ARC在编译…

python3GUI--仿win10任务管理器By:PyQt5(附UI源码)

文章目录 一.前言二.展示1.主界面1.进程2.性能1.CPU2.内存 3.简略信息4.详细信息5.新建任务 三.设计思路1.UI设计1.主界面1.进程2.性能3.详细信息4.新建任务5.图表信息组件 2.代码整体设计1.项目设计心得2.项目设计其他心得 3.其他心得 四&am…

华为无线ac+ap旁挂二层组网常用配置案例

AC控制器理解配置步骤: capwap source interface Vlanif 100 //源IP回包地址 wlan ssid-profile name test //新建个模版名称为test ssid test //wifi名称 wlan security-profile name test //建立安全模版也叫test security wpa-wpa2 psk pass-phrase admin123 a…

【PDFBox】PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档

这篇文章,主要介绍PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档。 目录 一、PDFBox操作文本 1.1、读取所有页面文本内容 1.2、读取指定页面文本内容 1.3、写入文本内容 1.4、替换文本内容 (1&#xf…

在 Amazon 上以高可用性模式实现 Microsoft SQL 数据库服务现代化的注意事项

许多企业都有需要 Microsoft SQL Server 来运行关系数据库工作负载的应用程序:一些应用程序可能是专有软件,供应商可使用它强制 Microsoft SQL Server 运行数据库服务;其他应用程序可能是长期存在的、自主开发的应用程序,它们在最…

XUbuntu22.04之vim无法复制内容到系统(一百八十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

将大模型集成到语音识别系统中的例子

概述 本文旨在探索将大型语言模型(LLMs)集成到自动语音识别(ASR)系统中以提高转录准确性的潜力。 文章介绍了目前的ASR方法及其存在的问题,并对使用LLMs的上下文学习能力来改进ASR系统的性能进行了合理的动机论证。 本…

VIM文本如何复制到系统剪切板?

今天从vim上用鼠标复制代码,发现把VIM当中的行号也复制进去了,就很麻烦,于是简单研究了下,如果vim支持clipboard的话就比较好办,具体支持与否,使用命令查看: vim --version | grep "clipb…

Android系统启动流程分析

当按下Android系统的开机电源按键时候,硬件会触发引导芯片,执行预定义的代码,然后加载引导程序(BootLoader)到RAM,Bootloader是Android系统起来前第一个程序,主要用来拉起Android系统程序,Android系统被拉起…