上一篇关于主要关于编码技巧,这一篇主要关于布局。

布局是Android应用里直接影响用户体验的一个关健部分。如果布局设计的不合理,可能导致你的应用大量的占用内存,出现假死等情况。

布局性能优化

Hierarchy Viewer——布局分析工具

概述

Android SDK提供了一个工具帮助你分析你的Layouts的性能问题——Hierarchy Viewer

结合这个工具同时查看本文,你能实现滑动流畅、占用内存最小的用户界面。

可以通过以下数据优化布局:
渲染出该布局的一个完整的item所需的时间

  • Measure:(测量)
  • Layout:(布局)
  • Draw:(绘制)

单位均为ms

使用

HierarchyViewer工具的jar包在skd/tools/目录下。

原本tools下应有个hierarchyviewer.bat。

记住它的名字:hierarchyviewer2lib-26.0.0-dev

好吧不用记,终端好像不能用命令打开了的样子...

The standalone version of hieararchyviewer is deprecated.
Please use Android Device Monitor (tools/monitor.bat) instead.

反正就是用Android Device Monitor来打开,Android Device Monitor打开的方式挺多的,

  1. 终端输入monitor
  2. 直接到目录打开bat文件
  3. 在Android studio菜单栏tools里去找 反正我是没找到
  4. 右上角菜单栏里找 反正我也是没找到

试图打开Android Device Monitor 遇到了如下错误

fileC:\Users\lin22AppData\LocalAndroid\Sdk\tools\lib\monitor-x86_64\configurati on\1556360813301.log

日志文件的话太长了....贴上来直接就说博客内容过长了 orz

网上资料大概分两种

  1. JDK版本不对
  2. 右键管理员权限打开,我反正是不管用

想想应该是版本问题,看了看我的 “up-to-date”版本的jdk,不禁猛男落泪....


再想想monitor既然已经被弃用了,使用Profile代替

However, most components of the Android Device Monitor are deprecated in favor of updated tools available in Android Studio 3.0 and higher.

然后在Android Studio 3.1之后,Hierarchy Viewer也已经移并不在开发使用Layout Inspector代替


重用布局和布局内嵌

为了提高你的Layouts的复用性,你也可以使用<include/>和<merge/>标签内嵌一个布局到另一个布局里。
布局重用是十分强大的,能让你产生可重用的复杂布局。

<include/>

比如:定义了一个title_bar——文件名为(title_bar.xml),被包含在每个activity的布局文件里。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/holo_orange_light"><ImageViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:src="@mipmap/ic_launcher" />
</FrameLayout>

然后在其他布局文件里就可以通过include导入如?

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><include layout="@layout/title_bar"/><ListViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/listView" /></android.support.constraint.ConstraintLayout>

在<include/>标签里,你也能重写所有的layout参数(任何android:layout_*属性)

然而,如果你想要用<include/>标签重写布局属性,为了其他的布局属性生效,你必须同时重写布局宽高两个属性

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

<merge/>

某些时候,自定义可重用的布局包含了过多的层级标签,比如我们需要在LinearLayout里面嵌入一个可重用的组件,而恰恰这个自定义的可重用的组件根节点也是LinearLayout,这样就多了一层没有用的嵌套,这样无疑只会拖慢程序速度。

而这个时候如果我们使用merge标签就可以避免那样的问题。

使用使用<include/>包含上面的布局的时候,系统会自动忽略merge层级,而把两个button直接放置与include平级

如?两个文件,title_bar被包含在LinerLayout,则它原本xml文件内外部的FrameLayout就显得浪费了

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><include layout="@layout/title_bar"/></LinearLayout><ListViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/listView" /></LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/holo_orange_light"><ImageViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:src="@mipmap/ic_launcher" />
</FrameLayout>

所以将?的FrameLayout改为merge,系统就会忽略merge这个标签,相当于直接放了一个ImageView到主布局的LinearLayout

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/holo_orange_light"><ImageViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:src="@mipmap/ic_launcher" />
</merge>

当然设置的背景色也会对应的失效  有需要的话需要移动出去 :)

在需要时加载视图

有时你的布局可能需要一些复杂却又很少被用到的视图。

无论他们是item详情、进度指示器,或撤销的消息,你都可以在需要的时候加载这些视图,来减少内存使用量并加快渲染速度。

通过定义一个ViewStub来实现?

  • ViewStub是一个没有尺寸大小并且不会在布局中嵌套或渲染任何东西的轻量级的视图。
  • 因此在视图层次展现或隐藏它的代价非常小。
  • 每一个ViewStub仅仅需要包含android:layout属性来展现指定的布局。

注意:

  • inflate()方法在视图渲染完毕后便直接展示该已渲染的视图View。因此,如果你需要和布局交互的话,不需要在调用findViewById()方法
  • 一个ViewStub是可见的后渲染完毕,该元素便不再是视图层次的一部分。它被已渲染的布局途欢,并且该布局的根视图的id是在ViewStub中被android:infatedId属性指定的id。(在android:id指定的id只有在这个ViewStub布局是可见、渲染完毕才是有效的)
  • ViewStub的一个缺点是,目前它在要渲染的布局中并不支持<merge/>标签

?下面提供一个完整的测试案例

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"><Buttonandroid:id="@+id/button_back"android:text="返回"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"/><Buttonandroid:id="@+id/button_ok"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintTop_toTopOf="parent"app:layout_constraintEnd_toEndOf="parent"android:text="完成" /></android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:background="@android:color/holo_orange_light"><ViewStubandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout="@layout/inc"android:id="@+id/stub_import"/><include layout="@layout/title_bar"/></LinearLayout><ListViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/listView" /></LinearLayout>
package com.example.a4_27layout_optimize;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewStub;
import android.widget.ImageView;
//imageview为title_bar里的imageviewpublic class MainActivity extends AppCompatActivity implements View.OnClickListener {private ImageView imageView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageView = findViewById(R.id.imageView);imageView.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId()==R.id.imageView){ViewStub vs = findViewById(R.id.stub_import);vs.setVisibility(View.VISIBLE);//或//View v = vs.inflate();}}
}

效果如?  点击图片才会去显示两个按钮

安卓性能优化——布局性能优化相关推荐

  1. ConstraintLayout如何优化布局性能

    参考: 了解使用 ConstraintLayout 的性能优势 原理: 减少了层级 在绘制视图时,是对视图树进行自顶而下的遍历操作,因此视图嵌套越多,设备绘制视图所需的时间和计算功耗就越多. 测量布局 ...

  2. 【Android 性能优化】布局渲染优化 ( GPU 过度绘制优化总结 | CPU 渲染过程 | Layout Inspector 工具 | View Tree 分析 | 布局组件层级分析 )

    文章目录 一. GPU 过度绘制优化总结 二. CPU 渲染过程 三. CPU 渲染性能调试工具 Layout Inspector 四. Layout Inspector 组件树 DecorView ...

  3. 【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | Android 系统的渲染优化 | 自定义布局渲染优化 )

    文章目录 一. 背景设置产生的过度绘制 二. Android 系统的渲染优化 1. 透明组件数据传递 2. GPU 存储机制 3. Android 7.0 之后的优化机制 三. 自定义布局渲染优化 一 ...

  4. 安卓性能优化之启动优化

    安卓性能优化之启动优化 两个定律 2-5-8原则 八秒定律 启动方式 冷启动 热启动 温启动 启动耗时统计 系统日志 adb命令 启动耗时分析 CPU Profile 工具介绍 使用方式 数据分析 C ...

  5. 安卓性能优化(响应优化)

    姊妹篇:性能优化(内存优化) 安卓app响应速度或使用流畅度是衡量性能的一个指标.如果一个应用用户启动应用时缓慢.使用时卡顿.甚至出现ANR那是很糟糕的体验. 通常,当应用无法响应用户输入时,系统即会 ...

  6. Android:最全面详细的性能优化攻略(含内存优化、内存泄漏、绘制优化、布局优化、图片优化、APK优化、多线程优化、列表优化等)

    前言:佛教中有一句话:初学者的心态,拥有初学者心态是件了不起的事情.真正的大师永远怀有一颗学徒的心. 一.概述 在Android中,性能优化是细分领域中最难且也是知识面涉及最深和最广的方向之一. 更快 ...

  7. 安卓开发者模式!Android性能优化之启动优化实战篇,深度好文

    除了Bug,最让你头疼的问题是什么?单身?秃头?996?面试造火箭,工作拧螺丝? 作为安卓开发者,除了Bug,经常会碰到下面这些问题: 应用卡顿,丢帧,屏幕画面撕裂,操作界面刷新缓慢,UI不美观,布局 ...

  8. Android开发——布局性能优化的一些技巧(一)

    0. 前言 上一篇我们分析了为什么LinearLayout会比RelativeLayout性能更高,意义在于分析了这两种布局的实现源码,算是对一个小结论的证明过程,但是对布局性能的优化效果,对这两种布 ...

  9. 【Android 性能优化】布局渲染优化 ( CPU 渲染优化 | 减少布局的嵌套 | 测量布局绘制时间 | OnFrameMetricsAvailableListener | 布局渲染优化总结 )

    文章目录 一. 减少布局嵌套 二. 布局渲染时间测量 1. FrameMetrics 使用流程 2. FrameMetrics 参数解析 3. FrameMetrics 代码示例 三. 布局渲染优化总 ...

  10. Android官方开发文档Training系列课程中文版:布局性能优化之布局层级优化

    原文地址:http://android.xsoftlab.net/training/improving-layouts/index.html 引言 布局是直接影响用户体验的关键部分.如果实现的不好,那 ...

最新文章

  1. Iphone 安装 ppsspp
  2. java取geosever数据,终于搞定了GeoServer的WFS查询
  3. 利用System.Net.Mail和多线程实现邮件发送
  4. java面向对象(this关键字)
  5. mysql 5.1 concat min_MySQL 5.1+ 数据库报错注入利用
  6. debian mysql中文乱码_MySQL中文乱码的解决方法汇总
  7. Docker之获取镜像(一)
  8. 静态网站与动态网站的区别 静态网站生成工具
  9. ASP.NET 4.0事件消息: 发生了验证错误;检测到有潜在危险的 Request.Form 值。
  10. MySQL 定时备份数据库(包含脚本)
  11. 口袋妖怪金心银魂详细图文攻略(下)及游戏下载
  12. 迪杰斯特拉(dijkstra)-两个地铁站最短距离
  13. 怎样根据电阻上的色环,判断电阻的大小
  14. STM32F4寄存器初始化系列:GPIO
  15. 大数据学习第一课:虚拟机安装配置
  16. SpringBoot+Vue项目毕业论文管理系统
  17. LaTeX排版(一):字体、页眉页脚、页边距、行距的设置
  18. 抽了一包华子才写出来的linux 文件目录结构详解
  19. linux中管道的概念,浅谈Linux管道
  20. 穷人家的孩子真的没戏了吗?道翰天琼认知智能机器人api接口平台为您解密-1!

热门文章

  1. 夜神模拟器如何设置自动代理
  2. | ERROR: [2] bootstrap checks failed. You must address the points described in the following [2] lin
  3. 前端屏幕尺寸和分辨率_移动端尺寸基础知识
  4. html鼠标悬停闪烁,鼠标悬停闪烁星星插件jQuery-canvas-sparkles
  5. python qq模块_用python写一个QQ机器人
  6. C300 OLT自动下发WAN连接指导配置
  7. 《The Selfish Giant》
  8. 微信公众号上传永久图片素材
  9. python主线程执行_python多线程学习一
  10. bluetooth Specification