Android性能优化——启动优化

news2024/11/26 23:41:14

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锁频

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git 新建本地仓库,推送到远程仓库

1、在项目的根目录右键 Git Bash Here 打开目录下的 git 命令 2、输入 git init 回车,初始化项目,把这个项目变成一个Git可以管理的仓库 项目根目录出现 .git 隐藏文件夹。这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面…

MateBook E Go Wi-Fi性能版(GK-W76)工厂模式win11原厂系统,含F10智能恢复功能

HUAWEI华为MateBook E平板笔记本电脑(GK-W76)原装出厂Windows11系统包,带F10一键智能还原 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、华为电脑管家等预装程序 所需要工具:16G或以上的U盘 文件格式:zip 文件大小:1…

Linux基础(三)端口、进程及主机状态管理、环境变量、文件管理

目录 端口 nmap netstat 进程管理 查看进程 关闭进程 主机状态监控 系统资源top命令 磁盘信息监控 网络状态监控 环境变量 $符号 自己设置环境变量 自定义环境变量PATH Linux的文件和下载 压缩和解压 tar命令 zip和unzip命令 端口 每个电脑有一个ip地址&#xff…

自动化测试(一):网页结构分析与Google翻译2023.7.18爬虫实例

目录 1. 网页分析1.1 静态网页1.2 静态网页的爬取案例1.3 动态网页1.4 Google翻译2023.7.18爬虫实例1.4.1 基于网页分析的Google翻译2023.7.18爬虫实例1.4.2 基于Selenium的Google翻译2023.7.18爬虫实例 1. 网页分析 网页分析即通过检查元素,确定想提取的内容的区域…

pyright 的配置方法

珍惜发量,拥抱python😂 可以很快的构建一个平台管理程序,嵌入式设备,芯片厂商,都是python 的示例代码了 Lua 真的很棒,值得嵌入式领域的推广 实时性要求不高的,嵌入式设备,可以考虑lua python PC 的程序 ,python/Rust/C &#xf…

波奇学Linux:冯诺依曼和进程

现代计算机大多是冯诺依曼体系结构,这是一种硬件结构,规定了设备组成和设备类型。 存储器:内存,磁盘/U盘是外存是输入输出设备。 输入设备:键盘/磁盘/摄像头/话筒/网卡 输出设备:显示器,播放器硬件&#…

Spring6 初始

Spring6 初始 文章目录 Spring6 初始每博一文案:1. 初始 Spring61.1 OCP开闭原则1.2 依赖倒置原则DIP1.3 控制反转IoC 2. Spring 初始2.1 Spring特点2.2 Spring6 的下载:2.3 Spring的jar文件 3. 第一个Spring 程序的编写4. 第一个Spring程序详细剖析4.1 bean标签的i…

SQL28 计算用户8月每天的练题数量

select day(date) as day,count(question_id) from question_practice_detail where month(date)8 and year(date)2021 group by date

C语言如何计算结构体大小(结构体的内存对齐)

前言: 结构体的内存对齐是有关结构体内容的很重要一个知识点,主要考察方式是计算结构体的字节大小。 引言: 当我们对计算结构体一无所知,我们不妨自己思索如何计算,是不是直接计算结构体成员变量占用内存的大小呢&a…

共享与协作:时下最热门的企业共享网盘推荐!

现代企业面临着越来越大的数据存储和共享压力。为了提高公司的生产力和效率,许多企业开始寻找共享网盘解决方案。这些共享网盘平台可以帮助企业集中管理文件和数据,并方便快速地与同事、客户或供应商共享。以下是几款好用的企业共享网盘。 Zoho Workdriv…

Android BlueToothBLE入门(三)——数据的分包发送和接收(源码已更新)

学更好的别人, 做更好的自己。 ——《微卡智享》 本文长度为3675字,预计阅读12分钟 前言 接上篇《Android BlueToothBLE入门(二)——设备的连接和通讯(附Demo源码地址)》最后提到过蓝牙BLE通讯每次默认发送…

qt 32位编译 内存溢出 无法 运行在win7 32位

项目在 编译32位系统 内存溢出 设置成了x64 但是 最后在xp32位系统运行提示 在下载了n个dll之后发现这种状况无穷无尽,后来在查阅资料时发现可以直接打开qt安装目录下的“vcredist”文件夹,将对应位数的程序拷到win7电脑上,直接运行&…

优化营商环境:构建智能营销平台,助力企业经营发展

对于企业来说,没有了客户,就像身体没有了血液,将失去生命力和活力,续存难发展更难。区域产业又是由一个个企业集聚而形成,企业的成败也就决定着区域产业的兴衰。 在当今竞争激烈的商业环境中,传统的销售手段…

基于python的爬虫实现

定义 爬虫(Web crawler),也被称为网络爬虫、网络蜘蛛或网络机器人,是一种自动化程序,用于浏览互联网并收集网页内容。 基本原理 爬虫的工作原理是通过发送HTTP请求从网页服务器获取网页的内容,然后解析网…

何时使用Windbg静态分析?何时使用Windbg动态调试?

目录 1、概述 2、使用Windbg静态分析dump文件 2.1、异常捕获模块自动生成dump文件 2.2、从Windows任务管理器中导出dump文件 2.3、从正在动态调试的Windbg中使用命令导出dump文件 2.4、使用Windbg静态分析dump文件的一般步骤 3、使用Windbg动态调试目标进程 3.1、程序发…

Win10 配置NDK安装2023.7.19版本

NDK安装流程 1. 下载:2. 安装:3. 测试: 在大多数情况下,使用 Android SDK 管理器安装 NDK 会更轻松。本文单独安装NDK,但后续也可以使用管理器进行管理。 1. 下载: 地址 Fig.1 最新稳定版本 2. 安装&…

精益生产的五大管理工具:提升效率,降低成本!

在制造业的世界里,精益生产是一种以追求在制造过程的各个方面减少浪费为中心的方法。为了实现这一目标,有几个经常使用的管理工具。这些工具使制造商能够识别和消除生产过程中任何效率低下或浪费的资源。本文将讨论精益生产中使用的一些关键管理工具&…

Android 进程与进程之间的通信--Messager 详细教程,两个app实现

Messenger是一种轻量级的IPC方案,它的底层实现其实就是AIDL.跨进程通信使用Messenger时,Messenger会将所有服务调用加入队列,然后服务端那边一次处理一个调用,不会存在同时调用的情况.而AIDL则可能是多个调用同时执行,必须处理多线程问 步骤详情 一、服务端 public class MyM…

如何使用DiskPart命令行格式化分区?

想要格式化磁盘分区,您可以使用磁盘管理工具,或在Windows文件资源管理器中右键单击驱动器并选择“格式化”。如果您更想使用命令行来格式化磁盘,那么Windows自带的DiskPart将是首选。 DiskPart有很多优点,例如,如果您想…

《无畏契约》游戏分析

文章目录 介绍游戏继承性《守望先锋》游戏美术对比游戏机制对比 《CSGO》游戏美术对比游戏机制对比 《英雄联盟》游戏美术对比游戏机制对比 《无畏契约》的优点《无畏契约》的缺点该游戏值得学习之处总结 介绍 《无畏契约(VALORANT)》是一款由拳头游戏&…