启动性能优化

一、应用启动慢的原因

1.在主线程执行了太多耗时的操作,比如加载数据,或者初始化三方库等等,导致在Application的oncreate或者Activity的oncreate方法中耗时太久
2.布局嵌套太深,或者一些不会立即使用的布局也在一开始一起加载到内存中

二、启动耗时统计

1.使用adb命令方式统计启动时间

adb shell amstart -S -W com.example.MainActivity

-S 表示杀掉当前进程然后重启该应用
-W 表示开启应用启动耗时日志
对应的打印如下:

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.appstartdemo/.MainActivity }
Warning: Activity not started, its current task has been brought to the front
Status: ok
Activity: com.example.appstartdemo/.MainActivity
ThisTime: 67
TotalTime: 67
WaitTime: 87
Complete

2.直接查看系统日志,在对应的DisPlayed关键字中,会统计应用启动到首个Activity绘制到屏幕上的时间,如下打印:

ActivityManager: Displayed com.example.appstartdemo/.MainActivity: +401ms

三、启动耗时分析

使用Android Studio自带的Profile,选择Trace Java Methods,然后开启Record,或者在Run 的时候选择Profile,就可以生成一段时间内的方法调用栈记录文件。我们通常可以用如下几种方式去打开这个Record文件:

1.火焰图(Frame Chart)方式

它会把相同的调用栈合并,然后根据执行的时间占比,生成一个个柱状图形,总体像火焰的样子。如下:
在这里插入图片描述
X轴:方法调用的时间占比,或者更精确地叫抽样数,即X轴越宽,则被抽中采样的次数越多,方法所消耗的时间就越长。
Y轴:表示调用栈,方法的调用链是由下而上的,每一个Y值都表示一个方法。
因此越在底部的方法,占用的时间就越多,因为这是方法的总入口。
柱子越高,说明调用链越深。
我们应该着重关注“平顶山”的情况,它表示柱子顶部X轴占比比较大,花费的时间比较长,这是消耗CPU的关键所在。

2.Top Down方式

显示一个调用链表中各个方法的具体执行耗时的时间值(微妙μs = 1000/1ms = 百万分之一秒),显示效果如下:
在这里插入图片描述
Total:表示该方法执行总体的耗时
Self:执行该方法本身的代码耗时,不包含子函数
Children:子函数的耗时
通过Top Down查看调用链,可以去分析耗时比较多的方法,然后去重点关注和优化。

四、启动性能优化方法

1.黑白屏的优化

由于冷启动一个新的应用,会存在一定的耗时,Google为了避免让程序看起来有延迟的情况出现,即用户点击图标后就会有即时的响应,会在App创建的过程中先显示一个空白页作为过渡。根据主题的不同,就会出现黑屏或者白屏时间比较长的情况,这是大部分用户无法容忍的,需要做优化。
优化的推荐方法是,首先自定义一个主题,继承当前的主题,然后设置它的windowbackground属性为一张跟业务相关的图片,也就是我们常见的欢迎界面,如下:

# 创建新的主题
<resources><style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"></style><style name="MyTheme" parent="AppTheme"><item name="android:windowFullscreen">true</item><item name="android:windowBackground">@drawable/launch_bg</item></style></resources>

然后在manifest文件中设置该主题:

# 在清单文件中给Activity设置主题
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.example.appstartdemo"><applicationandroid:theme="@style/AppTheme"><activityandroid:name=".MainActivity"android:theme="@style/MyTheme"></activity></application></manifest>

设置了windowbackground属性后,那么图片会一直存在;在启动完Activity之后,需要把主题重新设置回默认主题,避免背景图还一直存在。

# Activity启动后,设置回默认的主题
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {// 模拟耗时操作,显示更加的明显try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}setTheme(R.style.AppTheme);super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}
2.主线程的耗时优化

2.1避免在Application的oncreate方法或者Activity的oncreate方法中,去做过多的耗时操作,比如数据加载、网络请求、第三方库的初始化等等
2.2使用idleHandler去做耗时的数据加载和网络请求、三方库的初始化
2.3使用懒加载,只有在用到的时候,才去加载数据

3.布局优化

3.1使用include标签,去包含可以重复使用的布局,减少XML代码的冗余
3.2使用merge标签去作为被include的子布局文件的顶层布局,这样在被合并到主布局之后,就可以减少一层布局的嵌套
3.3使用ViewStub标签来引入一个子布局文件,最开始是不可见的,尺寸大小为0的控件。在启动Activity加载布局的时候,并不会把ViewStub的内容加载到View树里面,只有在对ViewStub执行setvisibility或者inflate的时候,才会去真正加载布局。这相当于是View的一种懒加载,对提高启动性能很有帮助。
对于那些最开始并不会用到的子View,或者那些一开始就设置gone的子View,适合使用ViewStub。

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

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

相关文章

Linux-Miniconda安装

下载miniconda安装文件 get "https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh" -O ~/miniconda.sh 如果是其它系统或者架构&#xff0c;访问地址获取对应安装脚本&#xff1a; https://mirrors.tuna.tsinghua.edu.cn…

Offlian RL: Weighted Policy Constraints for Offline Reinforcement Learning

AAAI 2023 paper Intro 分布偏移导致离线RL对于OOD数据存在过估计问题。因此一些方法限制策略靠近行为策略。但是着很大程度受限于数据集的质量。若是数据集存在非专家&#xff0c;一个自然的问题是是否有可能构建一个更合理的策略约束方法&#xff0c;该方法通过识别数据集中…

面试算法-111-课程表 II

题目 现在你总共有 numCourses 门课需要选&#xff0c;记为 0 到 numCourses - 1。给你一个数组 prerequisites &#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示在选修课程 ai 前 必须 先选修 bi 。 例如&#xff0c;想要学习课程 0 &#xff0c;你需要先完成…

SpringBoot 3整合Elasticsearch 8

这里写自定义目录标题 版本说明spring boot POM依赖application.yml配置新建模型映射Repository简单测试完整项目文件目录结构windows下elasticsearch安装配置 版本说明 官网说明 本文使用最新的版本 springboot: 3.2.3 spring-data elasticsearch: 5.2.3 elasticsearch: 8.1…

2024年软件测试岗现状?“我“进阶了测试开发,一路狂飙...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、测试工程师的现…

SM2098EHD:巴西双电压球泡灯应用

巴西使用的双电压系统主要包括127V和240V。这种双电压系统是为了适应不同的电器设备和需求。在巴西&#xff0c;有些电器设备可能需要127V的电压&#xff0c;而有些则可能需要240V的电压。 因此&#xff0c;如果你在巴西使用电器设备&#xff0c;需要确保设备能够适应巴西的双…

【数据结构】绪论

文章目录 开篇&#xff1a;数据结构的学习之路1、开篇_数据结构在学什么2、数据结构的基本概念数据数据元素、数据项数据结构、数据对象数据类型、抽象数据类型数据结构的三要素逻辑结构数据的物理结构&#xff08;存储结构&#xff09;数据的运算 最后总结内容 3、算法的基本概…

Linux 理解文件系统、磁盘结构、软硬链接

目录 一、理解磁盘结构 1、磁盘的物理结构 2、硬件层面理解 3、磁盘的具体物理存储结构 4、进行逻辑抽象 5、磁盘文件的管理 6、创建新文件的过程 二、理解文件系统 1、文件的构成 2、为何选择4KB而非512字节作为基本单位? 3、文件系统的组成 数据块&#xff08;Data Blocks&a…

图像抠图DIS——自然图像中高精度二分图像抠图的方法(C++/python模型推理)

概述 DIS&#xff08;Dichotomous Image Segmentation&#xff09;是一种新的图像分割任务&#xff0c;旨在从自然图像中分割出高精度的物体。与传统的图像分割任务相比&#xff0c;DIS更侧重于具有单个或几个目标的图像&#xff0c;因此可以提供更丰富准确的细节。 为了研究…

Oracle完全开发手册基础版(一篇学会所有Oracle所有知识点)

一、Oracle基础 1.简介 Oracle Database,又名Oracle RDBMS,或简称Oracle,是甲骨文公司的一款关系数据库管理系统。本课程主要介绍Oracle的SQL基础,包括表空间的概念,如何登录Oracle数据库,如何管理表及表中的数据,以及约束的应用。为后续课程的学习打下一个良好的基础…

Ubuntu20.04上,VTK9.3在QT5上的环境配置与开发测试

Ubuntu20.04上&#xff0c;VTK9.3在QT5上的环境配置与开发测试 1 背景介绍2 VTK9.3的编译安装2.1 安装ccmake 和 VTK 的依赖项&#xff1a;2.2 建立VTK编译文件夹并下载2.3 cmake配置VTK9.3的编译环境2.4 make编译安装VTK9.32.5 测试VTK安装是否成功 3 基于qmake的QT5的VTK9.3开…

Nginx中设置反向代理

在Nginx中设置反向代理&#xff0c;你需要使用proxy_pass指令。以下是一个简单的配置示例&#xff0c;它将Nginx配置为反向代理&#xff0c;将进入的流量转发到在本地运行的Web服务器上。 nginx http { server { listen 80; location / {proxy_pass http://localhost:8080;pro…

异地共享文件如何设置?

在当今数字化时代&#xff0c;异地办公已成为常态&#xff0c;越来越多的企业和个人需要在不同地区间进行文件共享与访问。为了解决复杂网络环境下的远程连接问题&#xff0c;北京金万维科技有限公司推出了一款名为【天联】的异地组网内网穿透产品。 【天联】组网是一款由北京金…

docker学习笔记 二-----docker介绍

老套路哈&#xff0c;第一章先科普一下三种常见的云服务类型&#xff0c;第二和第三章节写docker学习笔记。 一 、IAAS、PAAS、SAAS IAAS (Infrastructure as a Service)&#xff1a;基础即服务&#xff0c;供应商仅提供给用户最基础设施的服务资源&#xff0c;也就是服务器资…

2990: 【C3】【递推】蟠桃记

题目描述 喜欢西游记的同学肯定都知道悟空偷吃蟠桃的故事&#xff0c;你们一定都觉得这猴子太闹腾了&#xff0c;其实你们是有所不知&#xff1a;悟空是在研究一个数学问题&#xff01; 什么问题&#xff1f;他研究的问题是蟠桃一共有多少个&#xff01; 不过&#xff0c;到…

python基础——语句

一、条件语句 就是 if else 语句 &#xff01; 代表不等于 代表等于if 关键字&#xff0c;判断语句&#xff0c;有“如果”的意思&#xff0c;后面跟上判断语句else 常和“if” 连用&#xff0c;有“否则”的意思&#xff0c;后面直接跟上冒号 …

Offer必备算法17_子数组子串dp_八道力扣题详解(由易到难)

目录 ①力扣53. 最大子数组和 解析代码 ②力扣918. 环形子数组的最大和 解析代码 ③力扣152. 乘积最大子数组 解析代码 ④力扣1567. 乘积为正数的最长子数组长度 解析代码 ⑤力扣413. 等差数列划分 解析代码 ⑥力扣978. 最长湍流子数组 解析代码 ⑦力扣139. 单词拆…

qt学习第三天,qt设计师的第一个简单案例

3月25&#xff0c;应用qt设计师&#xff0c;手动设计界面形状 ​ 如何启动qt设计师&#xff0c;找到对应的安装地点&#xff0c;对应你自己安装的pyside6或其他qt的安装路径来找 ​ 应用qt设计师的优点是不用敲代码然后慢慢调节框框大小&#xff0c;位置等、可以直接修改…

TTS通用播放库技术设计

TTS音频播放库技术设计 目录介绍 01.整体介绍概述 1.1 项目背景介绍1.2 遇到问题1.3 基础概念介绍1.4 设计目标1.5 问题答疑和思考 02.技术调研说明 2.1 语音播放方案2.2 TTS技术分析2.3 语音合成技术2.4 方案选择说明2.5 方案设计思路2.6 文本生成音频 03.系统TTS使用实践 3…

Promise.all使用

故事背景&#xff1a; 在JavaScript中&#xff0c;经常会遇到需要同时执行多个异步操作的情况。而Promise.all方法提供了一种便捷的方式来处理这种情况&#xff0c;可以同时处理多个Promise对象&#xff0c;并等待它们全部完成后再执行后续操作。 Promise.all接受一个Promise对…