1.知识储备

  • CPU: 中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps、Drawables等都是一起打包到统一的纹理).

  • GPU:一个类似于CPU的专门用来处理Graphics的处理器, 作用用来帮助加快格栅化操作,当然,也有相应的缓存数据(例如缓存已经光栅化过的bitmap等)机制。

  • OpenGL ES是手持嵌入式设备的3DAPI,跨平台的、功能完善的2D和3D图形应用程序接口API,有一套固定渲染管线流程. 附相关OpenGL渲染流程资料

  • DisplayListAndroid把XML布局文件转换成GPU能够识别并绘制的对象。这个操作是在DisplayList的帮助下完成的。DisplayList持有所有将要交给GPU绘制到屏幕上的数据信息。

  • 格栅化 是 将图片等矢量资源,转化为一格格像素点的像素图,显示到屏幕上,过程图如下.

  • 垂直同步VSYNC:让显卡的运算和显示器刷新率一致以稳定输出的画面质量。它告知GPU在载入新帧之前,要等待屏幕绘制完成前一帧。下面的三张图分别是GPU和硬件同步所发生的情况,Refresh Rate:屏幕一秒内刷新屏幕的次数,由硬件决定,例如60Hz.而Frame Rate:GPU一秒绘制操作的帧数,单位是30fps,正常情况过程图如下.


2.渲染机制分析

渲染流程线

UI对象—->CPU处理为多维图形,纹理 —–通过OpeGL ES接口调用GPU—-> GPU对图进行光栅化(Frame Rate ) —->硬件时钟(Refresh Rate)—-垂直同步—->投射到屏幕

渲染时间线

Android系统每隔16ms发出VSYNC信号(1000ms/60=16.66ms),触发对UI进行渲染, 如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着计算渲染的大多数操作都必须在16ms内完成。

正常情况

渲染超时,计算渲染时间超过16ms

当这一帧画面渲染时间超过16ms的时候,垂直同步机制会让显示器硬件 等待GPU完成栅格化渲染操作,
这样会让这一帧画面,多停留了16ms,甚至更多.这样就这造成了 用户看起来 画面停顿.

当GPU渲染速度过慢,就会导致如下情况,某些帧显示的画面内容就会与上一帧的画面相同


3.渲染时会出现的问题

GPU过度绘制

GPU的绘制过程,就跟刷墙一样,一层层的进行,16ms刷一次.这样就会造成,图层覆盖的现象,即无用的图层还被绘制在底层,造成不必要的浪费.

过度绘制查看工具

在手机端的开发者选项里,有OverDraw监测工具,调试GPU过度绘制工具,
其中颜色代表渲染的图层情况,分别代表1层,2层,3层,4层覆盖.

我的魅族手机的Monitor GPU Rendering

计算渲染的耗时

任何时候View中的绘制内容发生变化时,都会重新执行创建DisplayList,渲染DisplayList,更新到屏幕上等一 系列操作。这个流程的表现性能取决于你的View的复杂程度,View的状态变化以及渲染管道的执行性能。

举个例子,当View的大小发生改变,DisplayList就会重新创建,然后再渲染,而当View发生位移,则DisplayList不会重新创建,而是执行重新渲染的操作.

当你的View过于复杂,操作又过于复杂,就会计算渲染时间超过16ms,产生卡顿问题.

渲染耗时呈现工具

工具中,不同手机呈现方式可能会有差别.分别关于StatusBar,NavBar,激活的程序Activity区域的GPU Rending信息。激活的程序Activity区域的GPU Rending信息。

界面上会滚动显示垂直的柱状图来表示每帧画面所需要渲染的时间,柱状图越高表示花费的渲染时间越长。

中间有一根绿色的横线,代表16ms,我们需要确保每一帧花费的总时间都低于这条横线,这样才能够避免出现卡顿的问题。

每一条柱状线都包含三部分,
蓝色代表测量绘制Display List的时间,
红色代表OpenGL渲染Display List所需要的时间,
黄色代表CPU等待GPU处理的时间。


4. 如何优化

有人会说这些小地方,不值得优化.但是当你用的是低配机器,内存到饱和,CPU运算到达饱和,就像一个界面要做很多交互,绘制,加载图片,请求网络.后,一个小问题就会导致页面卡顿(就像我手机的淘宝客户端…),OOM,项目崩溃.

是的,这就是力量~

Android系统已经对它优化

在Android里面那些由主题所提供的资源,例如Bitmaps,Drawables都是一起打包到统一的Texture纹理当中,然后再传递到 GPU里面,这意味着每次你需要使用这些资源的时候,都是直接从纹理里面进行获取渲染的。

我们要做的优化

扁平化处理,防止过度绘制OverDraw

1.每一个layout的最外层父容器 是否需要?

2.布局层级优化

进行检测时,可能会让多种检测工具冲突,用Android Device Monitor的时候,最好关闭相关手机上的开发者检测工具开关.
查看自己的布局,深的层级,是否可以做优化.
渲染比较耗时(颜色就能看出来),想办法能否减少层级以及优化每一个View的渲染时间.

Hierarchy Viewer工具

他是查看耗时情况,和布局树的深度的工具.

3.图片选择

Android的界面能用png最好是用png了,因为32位的png颜色过渡平滑且支持透明。jpg是像素化压缩过的图片,质量已经下降了,再拿来做9path的按钮和平铺拉伸的控件必然惨不忍睹,要尽量避免。

对于颜色繁杂的,照片墙纸之类的图片(应用的启动画面喜欢搞这种),那用jpg是最好不过了,这种图片压缩前压缩后肉眼分辨几乎不计,如果保存成png体积将是jpg的几倍甚至几十倍,严重浪费体积。

4.清理不必要的背景

5.当背景无法避免,尽量用Color.TRANSPARENT

因为透明色Color.TRANSPARENT是不会被渲染的,他是透明的.



//优化前
//优化前: 当图片不为空,ImageView加载图片,然后统一设置背景
Bean bean=list.get(i);
if (bean.img == 0) {
Picasso.with(getContext()).load(bean.img).into(holder.imageView);
}
chat_author_avatar.setBackgroundColor(bean.backPic);
//优化后
//优化后:当图片不为空,ImageView加载图片,并设置背景为TRANSPARENT;
//当图片为空,ImageView加载TRANSPARENT,然后设置背景为无照片背景
Bean bean=list.get(i);
if (bean.img == 0) {
Picasso.with(getContext()).load(android.R.color.transparent).into(holder.imageView);
holder.imageView.setBackgroundColor(bean.backPic);
} else {
Picasso.with(getContext()).load(bean.img).into(holder.imageView);
holder.imageView.setBackgroundColor(Color.TRANSPARENT);
}

————-对比结果——————–

6.优化自定义View的计算

View中的方法OnMeasure,OnLayout,OnDraw.在我们自定义View起到了决定作用,我们要学会研究其中的优化方法.

学会裁剪掉View的覆盖部分,增加cpu的计算量,来优化GPU的渲染


/**
* Intersect the current clip with the specified rectangle, which is
* expressed in local coordinates.
*
* @param left The left side of the rectangle to intersect with the
* current clip
* @param top The top of the rectangle to intersect with the current clip
* @param right The right side of the rectangle to intersect with the
* current clip
* @param bottom The bottom of the rectangle to intersect with the current
* clip
* @return true if the resulting clip is non-empty
*/
public boolean clipRect(float left, float top, float right, float bottom) {
return native_clipRect(mNativeCanvasWrapper, left, top, right, bottom,
Region.Op.INTERSECT.nativeInt);
}

5.总结

性能优化其实不仅仅是一种技术,而是一种思想,你只听过它的高大上,却不知道它其实就是各个细节处的深入研究和处理.

当然,有的时候也需要自己进行权衡效果和性能,根据需求进行选择.

还有,Android Device Monitor 是个好东西~简直就是性能优化大本营,性能优化的工具基本都在其中.

所以在平时的开发过程中,养成良好的思考习惯,是第一步~

写代码的时候要想:
1.你的代码是不是多余?
2.你的对象有没有必要在循环中创建?
3.你的计算方法是不是最优?

画界面的时候要想:
1.布局是否有背景?
2.是否可以删掉多余的布局?
3.自定义View是否进行了裁剪处理?
4.布局是否扁平化,移除非必需的UI组?

最后,Android Device Monitor 是个好东西~ 性能优化的工具基本都在其中.

深入Android渲染机制的更多相关文章

  1. Android渲染机制和丢帧分析

    http://blog.csdn.net/bd_zengxinxin/article/details/52525781 自己编写App的时候,有时会感觉界面卡顿,尤其是自定义View的时候,大多数是因 ...

  2. 理解WebKit和Chromium: Chromium WebView和Chrome浏览器渲染机制

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 数据对比 前面介绍过Chromium WebView的时候,说过有关ChromiumWebView同Chrom ...

  3. Android群英传笔记——第六章:Android绘图机制与处理技巧

    Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...

  4. Android运行机制

    一. Android平台各层 Android平台架构图,如下图:由上到下依次为应用程序.应用程序框架.库.Android运行时.Linux内核. 1.Linux内核: Android系统基于Linux ...

  5. Android Handler机制彻底梳理

    Android的消息机制其实也就是Handler相关的机制,对于它的使用应该熟之又熟了,而对于它的机制的描述在网上也一大堆[比如15年那会在网上抄了一篇https://www.cnblogs.com/ ...

  6. 深入理解Android消息机制

    在日常的开发中,Android 的消息机制作为系统运行的根本机制之一,显得十分的重要. 从 Handler 发送消息开始 查看源码,Handler的post.send方法最终都会走到 public f ...

  7. 高级UI晋升之View渲染机制(二)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...

  8. Android随笔之——Android广播机制Broadcast详解

    在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理.这个广播跟我们传统意义中的电台广播有些相似之处.之所以叫做广播,就 ...

  9. Android广播机制的深入学习

    部分内容转载自http://www.cnblogs.com/lwbqqyumidi/p/4168017.html 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者 ...

随机推荐

  1. Android工具 Hierarchy Viewer 分析

    Hierarchy Viewer是随AndroidSDK发布的工具,位置在tools文件夹下,名为hierarchyviewer.bat.它是Android自带的非常有用而且使用简单的工具,可以帮助我 ...

  2. ubuntu14.04 不能关机,一直停在关机界面

    1.emotion: 最近在使用Ubuntu14.04 LTS时,输入shutdown -h now之后,Ubuntu就一直停在关机界面,始终不能shutdown,不得不手动按下电源button.忍受 ...

  3. layer弹窗在键盘按回车将反复刷新

      条件:弹窗后不做任何点击操作或者聚焦操作对于layer.load,弹出后反复按回车,load层将不断刷新,即使设置了自动消失也只有等不按回车键才会生效.对于layer iframe层有表单就更糟糕 ...

  4. 在SAE搭建微信公众账号服务

    让我们回到2014年11月,从公司请假回成都,在天府软件园B区旁边的小区里,那个10多平米的出租屋里,闲来无事,我想找个事情做一做,好让我这漂浮的心静下来.大约在半年前就申请了微信的一个公众账号,一直 ...

  5. restful的nginx配置方法

    location /{ root /webserver/www/a.tk.com; index index.html index.htm index.php; if ( $document_uri ~ ...

  6. 关于ubuntu的对拍

    感谢夏天dl的blog,写的十分清楚,但是本人对于ubuntu十分不熟悉 所以不怎么会使用. 对拍的可执行文件是sh,就是bash语言 #!bin/bash while true; do ./date ...

  7. d3 根据数据绘制svg

    , , , , ]; var circles = svg.selectAll("circle") .data(dataset) .enter() .append("cir ...

  8. 聊聊 Spring Boot 2.0 的 WebFlux

    聊聊 Spring Boot 2.0 的 WebFlux## 前言 对照下 Spring Web MVC ,Spring Web MVC 是基于 Servlet API 和 Servlet 容器设计的 ...

  9. STL学习笔记(七) 程序中使用STL

    条款43:算法调用优先于手写循环 class Widget { public: bool test(); }; vector<Widget> vec; 算法调用: for_each(vec ...

  10. Java-线索二叉树的实现

    概念性的东西,自行百度. 按照国际管理,直接上代码来分析. 1.Node节点类 package com.tree.thread; /** * Author: lihao * Date:2017/8/3 ...