Android中级——性能优化

news2024/11/22 23:31:40

性能优化

  • 布局优化
    • UI渲染机制
    • 避免Overdraw
    • 优化布局层级
    • 利用<include\>重用Layout
    • 使用<ViewStub\>实现View的延迟加载
    • Hierarchy View
  • 内存优化
    • 获取内存信息
    • Profiler
    • TraceView
    • MAT(Memory Analyzer Tool)
  • dumpsys

布局优化

UI渲染机制

  • 画面流畅需要帧数为60帧每秒
  • Android通过VSYNC信号触发对UI的绘制,其间隔时间是1000ms/60=16ms(即1000ms内显示60帧画面的单位时间)
  • 故需在16ms之内完成绘制才可以保证画面的流畅
  • 否则会造成丢帧,如一次绘制耗时20ms,当16ms时系统发出VSYNC信号还未绘制完,下一个帧就会被丢弃,直到下次信号才开始绘制,导致16*2ms内都显示同一帧画面(即卡顿)

利用 开发者选项 / Profile GPU Rendering / On srceen as bars 工具可检查UI渲染时间

  • 蓝色:测量绘制Display List的时间
  • 红色:OPenGL渲染Display List所需要的时间
  • 黄色:CPU等待GPU处理的时间
  • 绿色横线:VSYNC时间16ms,需尽量将所有条形图控制在绿线下
    在这里插入图片描述

避免Overdraw

过度绘制会浪费CPU、GPU资源,如系统会默认绘制Activity的背景,若再绘制一个重叠背景则Overdraw了

利用 开发者选项 / Enable GPU Overdraw工具可通过颜色判断Ovedraw的次数,颜色越深表示绘制次数越多

在这里插入图片描述

优化布局层级

对View的测量、布局和绘制都是通过对View树的遍历来操作,建议View树的高度不超过10层,如将RelativeLayout替换嵌套的LinearLayout降低高度

利用<include>重用Layout

如下为一个共性的TextView,将宽高设为0可让开发者在使用时对其赋值

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:textSize="30sp"
    android:text="common ui">
</TextView>

通过include的layout属性引用

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
        layout="@layout/common_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

使用<ViewStub>实现View的延迟加载

如查看的内容只有在点击某个按钮时才会加载

  • ViewSub只会在显示时才去渲染布局
  • setVisibility(View.GONE)在初始化布局树的时候就已经添加布局

如下为要加载的view_stub_item.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/ic_launcher">
</ImageView>

主布局中ViewStub通过layout属性引用布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/vis"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="visible" />

    <Button
        android:id="@+id/inflate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="inflate" />

    <ViewStub
        android:id="@+id/viewStub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/view_stub_item" />

</LinearLayout>

获取到ViewStub后,可利用以下两种方式加载

  • setVisibility(View.VISIBLE)
  • inflate(),还可以返回被inflate的Layout
public class MainActivity extends AppCompatActivity {

    ViewStub viewStub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewStub = (ViewStub) findViewById(R.id.viewStub);
        findViewById(R.id.vis).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewStub.setVisibility(View.VISIBLE);
            }
        });
        findViewById(R.id.inflate).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                View inflateView = viewStub.inflate();
                ImageView imageView = (ImageView) inflateView.findViewById(R.id.img);
            }
        });
    }
}

Hierarchy View

通过SDK/Tool/monitor.bat,打开Android Device Monitor(打开先需关闭AS),再运行程序,布局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

在Hierarchy View,我们可以看到三层的LinearLayout且没有分支,说明是冗余的

在这里插入图片描述

选择某个View,点击右上角的"Obtain layout time…",可获取布局测量、摆放、绘制的时间,绿黄红颜色表示绘制效率的好中差

在这里插入图片描述

内存优化

获取内存信息

在开发者模式中找到内存相关信息

在这里插入图片描述

Profiler

可利用AS底部的Profiler实时监控程序的内存使用情况

  • 当内存泄漏时,内存会持续增高
  • 当发生GC时,内存会突然减少

在这里插入图片描述

TraceView

TraceView是一个可视化性能调查工具,用于分析TraceView log,可利用Debug类在onCreate()开启监听,onDestroy()时结束监听

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Debug.startMethodTracing();
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Debug.stopMethodTracing();
    }
}

生成的dmtrace.trace存放在以下路径

在这里插入图片描述

此外,还可以通过Android Device Monitor的start method profiling

  • Trace:跟着方法执行的全部过程,资源消耗大
  • Sample:按照指定频率抽样调查,需要较长执行时间获取准备样本

在这里插入图片描述
用Android Device Monitor打开生成的Log,上半部分显示方法执行时间的时间轴,每一行代表一个线程,不同颜色的方块代表下面不同的执行方法

在这里插入图片描述

下半部分为具体方法在所处时间段内的各种类型时间及所占百分比

  • Incl CPU Time——某方法占用的CPU时间
  • Excl CPU Time——某方法本身(不包括子方法)占用的CPU时间
  • Incl Real Time——某方法真正执行时间
  • Excl Real Time——某方法本身(不包括子方法)真正执行时间
  • Calls+RecurCalls——调用次数+递归回调次数

如果Incl CPU Time时间长,但Calls+RecurCalls次数少,则应该优化方法

MAT(Memory Analyzer Tool)

点击Android Device Monitor的Update Heap更新堆数据,在Heap标签点击Cause GC,再点击Dump HPROF File保存文件

在这里插入图片描述

利用Sdk\platform-tools\hprof-conv.exe转换格式

在这里插入图片描述

打开MAT选择Open Dump File

在这里插入图片描述

  • Histogram:查看内存中每个对象的数量、大小和名称
  • Dominator Tree:按照对象大小进行排序,并显示对象之间的引用结构,可找出大对象

dumpsys

dumpsys 可以列出系统相关的信息和服务状态

命令功能
activityActivity栈信息
meminfo内存信息
procstats内存状态
package包信息

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

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

相关文章

透过Gartner最新报告,认识“超级边缘”

当下&#xff0c;酝酿能量的超级边缘。最近&#xff0c;我们在谈视频化狂飙、谈AIGC颠覆、谈算力动能不足&#xff0c;很少谈及边缘。但“边缘”恰恰与这一切相关&#xff0c;且越发密不可分&#xff0c;它是未来技术发展的极大影响因子。 “到2025年&#xff0c;超过70%的组织…

Segment Anything Model

论文翻译&#xff1a; 图1&#xff1a;我们旨在通过引入三个相互关联的组件来构建分割的基础模型&#xff1a;即时分割任务、支持数据注释并通过即时工程将零样本传输到一系列任务的分割模型&#xff08;SAM&#xff09;&#xff0c;以及用于收集SA-1B的数据引擎&#xff0c;SA…

MappingGenerator PRO 2023.3 Visual Studio 2019-2022

您的私人编码助手 MappingGenerator 最初是作为 AutoMapper 的设计时替代品创建的。现在它正在演变为编码助手&#xff0c;您可以将最平凡的编码任务委派给它&#xff1a; 生成映射生成显式转换实施克隆生成投影表达式脚手架方法调用脚手架对象创建清理方法调用方便ILogger的使…

探讨Hive是否转为MapReduce程序

目录 前提条件 数据准备 探讨HQL是否转为MapReduce程序执行 1.设置hive.fetch.task.conversionnone 2.设置hive.fetch.task.conversionminimal 3.设置hive.fetch.task.conversionmore 前提条件 Linux环境下安装好Hive&#xff0c;这里测试使用版本为&#xff1a;Hive2.3.…

【结构型模式】适配者模式

文章目录优秀借鉴1、简介2、结构3、实现方式3.1、案例引入3.2、类适配器3.3、对象适配器3.4、接口适配器4、区别对比5、适配者模式优缺点6、应用场景优秀借鉴 黑马程序员Java设计模式详解-适配器模式概述适配器设计模式&#xff08;封装器模式&#xff09;一文彻底弄懂适配器模…

页眉怎么添加【节】,设置不同章节不同页眉

文章目录前言添加【节】&#xff0c;设置不同内容总结前言 大家写文档或者论文的时候可能会需要&#xff1a;不同章节页眉展示不同的内容 然而&#xff0c;在双击页眉进行编辑的时候却发现几个章节的页眉一起被修改了&#xff1a; 会出现文章与页眉不同步的情况&#xff0c…

idea使用Junit

文章目录 idea使用JunitJunit配置常用注解常用于测试的断言方法后续idea使用Junit 对项目使用Junit主要有两个步骤: 添加Junit依赖,即添加Junit jar包使用JunitJunit配置 方法一:idea自带的快捷方法 对要测试的类的方法,在该类中,右键鼠标呼出菜单,选择Generate,快捷…

简单的回顾Linux

linux命令ls会显示出文件的颜色, 系统约定的默认颜色含义如下: 白色&#xff1a;表示普通文件 蓝色&#xff1a;表示目录 绿色&#xff1a;表示可执行文件 红色&#xff1a;表示压缩文件 浅蓝色&#xff1a;链接文件 主要是使用ln命令建立的文件 红色闪烁&#xff1a;表示链接的…

Java实现打印杨辉三角形,向左、右偏的平行四边形这三个图形代码程序

目录 前言 一、打印杨辉三角形 1.1运行流程&#xff08;思想&#xff09; 1.2代码段 1.3运行截图 二、向左偏的平行四边形 1.1运行流程&#xff08;思想&#xff09; 1.2代码段 1.3运行截图 三、向右偏的平行四边形 1.1运行流程&#xff08;思想&#xff09; 1.2代…

inplace-operation-error 【已解决】

最近在搞CT医学图像分割模型的领域泛化优化&#xff0c;结果就出现了报错&#xff1a; 关于这个问题stackoverflow上有非常多的讨论&#xff0c;可以过去围观&#xff1a; 指路&#xff1a;中文版stackoverflow - 堆栈内存溢出 (stackoom.com) Stack Overflow - Where Develo…

UNET-RKNN分割眼底血管

前言 最近找到一个比较好玩的Unet分割项目&#xff0c;Unet的出现就是为了在医学上进行分割(比如细胞或者血管)&#xff0c;这里进行眼底血管的分割&#xff0c;用的backbone是VGG16&#xff0c;结构如下如所示(项目里面的图片&#xff0c;借用的&#xff01;借用标记出处&…

C语言函数大全--h开头的函数

C语言函数大全 本篇介绍C语言函数大全–h开头的函数或宏 1. hypot&#xff0c;hypotf&#xff0c;hypotl 1.1 函数说明 函数声明函数功能double hypot(double x, double y);计算直角三角形的斜边长&#xff08;double&#xff09;float hypotf (float x, float y);计算直角…

UPA/URA双极化天线的协方差矩阵结构

文章目录UPA的阵列响应向量&#xff08;暂不考虑双极化天线&#xff09;UPA阵列响应&#xff1a;从单极化天线到双极化天线UPA双极化天线的协方差矩阵结构参考文献UPA的阵列响应向量&#xff08;暂不考虑双极化天线&#xff09; 下图形象描述了UPA阵列的接收信号 UPA阵列的水平…

【springcloud 微服务】Spring Cloud 微服务网关Gateway使用详解

目录 一、微服务网关简介 1.1 网关的作用 1.2 常用网关 1.2.1 传统网关 1.2.2 云原生网关 二、gateway网关介绍 2.1 问题起源 2.2 引发的问题 2.2.1 重复造轮子 2.2.2 调用低效 2.2.3 重构复杂 2.3 gateway改进 三、Spring Cloud Gateway 介绍 3.1 Gateway 概述 …

【JSON学习笔记】3.JSON.parse()及JSON.stringify()

前言 本章介绍JSON.parse()及JSON.stringify()。 JSON.parse() JSON 通常用于与服务端交换数据。 在接收服务器数据时一般是字符串。 我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象。 语法 JSON.parse(text[, reviver])参数说明&#xff1a; text:必需&…

Angular可视化指南 - 用Kendo UI图表组件创建数据可视化

Kendo UI for Angular是专业级的Angular UI组件库&#xff0c;不仅是将其他供应商提供的现有组件封装起来&#xff0c;telerik致力于提供纯粹高性能的Angular UI组件&#xff0c;而无需任何jQuery依赖关系。无论您是使用TypeScript还是JavaScript开发Angular应用程序&#xff0…

【机器学习(二)】线性回归之梯度下降法

文章目录专栏导读1、梯度下降法原理2、梯度下降法原理代码实现3、sklearn内置模块实现专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN Python领域新星创作者&#xff0c;专注于分享python领域知识。 ✍ 本文录入于《数据分析之术》&#xff0c;本专栏精选了经典的机器…

1漏洞发现

漏洞发现-操作系统之漏洞探针类型利用修复 一、操作系统漏洞思维导图 相关名词解释&#xff1a; CVSS&#xff08;Common Vulnerability Scoring System&#xff0c;即“通用漏洞评分系统”&#xff09; CVSS是安全内容自动化协议&#xff08;SCAP&#xff09;的一部分通常C…

rockchip rk3588添加uvc及uvc,adb的复合设备

软硬件环境&#xff1a; 软件基础&#xff1a;我目前拿到的rk3588 sdk &#xff1a;gitwww.rockchip.com.cn:2222/Android_S/rk3588- manifests.git硬件基础&#xff1a;RK3588 LP4X EVB uvc_app: 从rv1126 sdk中rv1126_sdk/rv1126/external/uvc_app 目录移植而来。移植后&…

能翻译大量文字的软件-正规的翻译软件

复制自动翻译软件是一种能够复制并自动翻译文本的工具。当您阅读某一种语言的文本时&#xff0c;这种软件可以快速识别并翻译出来&#xff0c;以方便您更好地理解内容。与其他翻译软件不同的是&#xff0c;复制自动翻译软件可以直接在游览网站的过程中&#xff0c;直接对用户正…