Android开发之性能优化:过渡绘制解决方案

这篇具有很好参考价值的文章主要介绍了Android开发之性能优化:过渡绘制解决方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 过渡绘制

屏幕上某一像素点在一帧中被重复绘制多次,就是过渡绘制。
下图中多个卡片跌在一起,但是只有第一个卡片是完全可见的。背后的卡片只有部分可见。但是Android系统在绘制时会将下层的卡片进行绘制,接着再将上层的卡片进行绘制。但其实,下层卡片不可见的部分是不需要进行绘制的,只有可见部分才需要进行绘制。

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

依据过渡绘制的层度可以分成:

  • 无过渡绘制(一个像素只被绘制了一次)
  • 过渡绘制x1(一个像素被绘制了两次)
  • 过渡绘制x2(一个像素被绘制了三次)
  • 过渡绘制x3(一个像素被绘制了四次)
  • 过渡绘制x4+(一个像素被绘制了五次以上)

2. 查看自己应用的过渡绘制情况

方法一:通过开发者选项开启GPU过渡绘制调试

Android手机的开发者选项中有『调试 GPU 过度绘制』的选项:

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

点开后后选择『显示过渡绘制区域』:

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

方法二:通过adb命令开启GPU过渡绘制调试

当然,如果每次都进入系统设置嫌麻烦,可以使用adb命令进行开启和关闭:
开启『调试 GPU 过度绘制』:

adb shell setprop debug.hwui.overdraw show

关闭『调试 GPU 过度绘制』:

adb shell setprop debug.hwui.overdraw false

执行命令之后可能需要重新启动你当前开发的应用。

颜色与过渡绘制:

  • 原色:没有过度绘制
  • 蓝色:1 次过度绘制
  • 绿色:2 次过度绘制
  • 粉色:3 次过度绘制
  • 红色:4 次及以上过度绘制

在平时的开发中,如果出现粉色及以上的过渡绘制情况。说明过渡绘制以及很严重了。需要进行优化。

3. 优化过渡绘制

1. 去除Activity自带的默认背景颜色:

查看Android源码里的Theme主题,如下:

<style name="Theme">
    ...
    <!-- Window attributes -->
    <item name="windowBackground">@drawable/screen_background_selector_dark</item>
    ...
</style>

也就是说继承Theme这个style的风格,默认情况下,新建一个Activity都是有背景的。正常情况下,很多界面其实是不需要背景的。

下面是华为自带天气APP的首页,我们可以看到文字部分以及图标部分都是绿色,说面已经是第三层过渡绘制了,其中背后天气图是一层,文字又是一层,正常来说应该只有两层,也就是文字和图标应该是蓝色。

那么这多出来的一层应该就是Activity自带的背景色了。也就是theme里面设置的。

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

我们只要在自己的AppTheme里面去除该背景色即可:

<style name="AppTheme" parent="android:Theme.Light.NoTitleBar">
    <item name="android:windowBackground">@null</item>
</style>

或者在Activity的onCreate方法中:

getWindow().setBackgroundDrawable(null);

2. 使用Canvas的clipRect和clipPath方法限制View的绘制区域

一个Activity对应有一个Canvas,也就是画布,画布的概念就是一个画板,这个画布提供了很多的API,我们可以通过调用画布的API来绘图以及对画布做一些操作,clipRect方法用来裁切画布上的一个矩形区域,该矩形区域用Rect对象来描述。调用了clipRect之后,画布的可绘制区域减小到和Rect指定的矩形区域一样大小。所有的绘制将限制在该矩形范围之内。这里的裁切概念和PS里的裁切类似。

典型的例子,抽屉布局,找了网易云音乐开刀:

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

注意观察左侧抽屉打开的时候,抽屉布局和背后布局重叠在一起了,此时整个屏幕一多半都变成了红色,过渡绘制严重。

在抽屉布局弹出时,抽屉布局是不透明的,也就是说抽屉布局背后挡住的内容布局是不需要绘制的,而网易云进行了绘制,导致抽屉布局所在区域的像素点绘制了多次。

google官方在android.support.v4.widget包下有DrawerLayout.Java类。使用来实现抽屉布局的。该类在重写了drawChild方法:

@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
    final int height = getHeight();
    // 判断是否是内容视图
    final boolean drawingContent = isContentView(child);
    int clipLeft = 0, clipRight = getWidth();

    // 记录当前画布信息
    final int restoreCount = canvas.save();
    if (drawingContent) {
        // 只有在绘制内容视图时才进行裁切
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View v = getChildAt(i);
            if (v == child || v.getVisibility() != VISIBLE ||
                    !hasOpaqueBackground(v) || !isDrawerView(v) ||
                    v.getHeight() < height) {
                // 如果child是内容视图/视图不可见/视图背景透明/不是抽屉视图/child高度小于父布局高度
                // 则不做画布裁切
                continue;
            }

            if (checkDrawerViewAbsoluteGravity(v, Gravity.LEFT)) {
                // 盒子在左侧时裁切的left和right
                final int vright = v.getRight();
                if (vright > clipLeft) clipLeft = vright;
            } else {
                // 盒子在右侧时裁切的的left和right
                final int vleft = v.getLeft();
                if (vleft < clipRight) clipRight = vleft;
            }
        }
        // 裁切画布
        canvas.clipRect(clipLeft, 0, clipRight, getHeight());
    }
    // 绘制子视图
    final boolean result = super.drawChild(canvas, child, drawingTime);
    // 回复到裁切之前的画布
    canvas.restoreToCount(restoreCount);
}

drawChild方法在ViewGroup类的dispatchDraw方法内被调用,用来绘制子视图,DrawerLayout类通过重写该方法,因为在所有孩子视图绘制之前都会调用drawChild方法,但是这里只需要对内容区域视图做裁切,当绘制内容区域视图时,取得抽屉视图的位置信息,如果抽屉视图可见、背景为不透明、抽屉高度和父布局高度一致时,取得抽屉视图左、上、右、下边缘在canvas中的位置信息。接着进行裁切,将内容视图未被挡住的部分区域裁切出来,并把裁切完的canvas交由子View进行绘制,这样,内容区域只有在裁切后的区域才会绘制,其他区域不进行绘制。

待子View绘制完之后,恢复Canvas到裁切之前的状态,因为一个Window下的所有View都使用的是同一个Canvas,所以需要恢复状态给其他子View使用。

下面看一个系统里的“下载”APP,使用的是DrawerLayout实现:

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

应用中虽然内容区域是红色,但是抽屉视图拉出来之后,抽屉视图的过渡绘制情况却比内容区域未被挡住的部分少。

3. ImageView的background和imageDrawable重叠

Android中,所有的view均可以设置background。ImageView除了能够设置background之外,还能设置ImageDrawable。

在开发中,很多时候需要显示图片,在图片加载出来之前通常是需要显示一张默认图片的,很多时候会使用ImageView的background属性来设置默认背景图,而imageDrawable来设置需要加载的图片。这样会导致一个问题,当图片加载到页面后,默认背景图被挡住了,但是却任然需要绘制,导致过渡绘制情况的发生。

解决方案是把背景图和真正加载的图片都通过imageDrawable方法进行设置。

4. 总结

  • Android中一个window对应一个Canvas,window下的所有视图(View/ViewGroup)使用的都是同一个canvas,视图树的父节点在调用子视图的View.draw之前,会对Canvas进行裁切,裁切的区域就是View在屏幕中所占的矩形区域,这也就是为什么超过View边界的内容会被裁切掉的原因。

  • 既然过渡绘制值一个像素点被绘制多次,我们只要保证图片或者背景颜色不要叠加在一起即可。正确的方式应该是尽量减少带背景的View产生重叠区域。如果重叠,使用canvas的clipRect进行裁切。

  • 尽量减少视图的深度,来减少视图树的遍历过程。

最后

最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

为了帮助到大家更好的全面清晰的掌握好性能优化,准备了相关的核心笔记(还该底层逻辑):https://qr18.cn/FVlo89

性能优化核心笔记:https://qr18.cn/FVlo89

启动优化
Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构
内存优化
Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构
UI优化
Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构
网络优化
Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构
Bitmap优化与图片压缩优化https://qr18.cn/FVlo89
Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构
多线程并发优化与数据传输效率优化
Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构
体积包优化
Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

《Android 性能监控框架》:https://qr18.cn/FVlo89

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构

《Android Framework学习手册》:https://qr18.cn/AQpN4J

  1. 开机Init 进程
  2. 开机启动 Zygote 进程
  3. 开机启动 SystemServer 进程
  4. Binder 驱动
  5. AMS 的启动过程
  6. PMS 的启动过程
  7. Launcher 的启动过程
  8. Android 四大组件
  9. Android 系统服务 - Input 事件的分发过程
  10. Android 底层渲染 - 屏幕刷新机制源码分析
  11. Android 源码分析实战

Android开发之性能优化:过渡绘制解决方案,性能优化,Android,移动开发,android,性能优化,移动开发,framework,软件架构文章来源地址https://www.toymoban.com/news/detail-671840.html

到了这里,关于Android开发之性能优化:过渡绘制解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android开发实战经典,设计思想与代码质量优化+程序性能优化+开发效率优化

    一、关于Handler面试那些问题 1、Handler Looper Message 关系是什么? 2、Messagequeue 的数据结构是什么?为什么要用这个数 据结构? 3、如何在子线程中创建 Handler? 4、Handler post 方法原理? 5、Android 消息机制的原理及源码解析 6、Android Handler 消息机制 7、Android 消息机制 … 二、关于

    2024年03月11日
    浏览(122)
  • Android开发之性能优化工具Profiler

    性能优化问题,在我们开发时都会遇到,但是在小厂和对自己要求不严格的情况下,我都很少去做性能优化; 在性能优化上,基本大家都是通过自己的开发经验和性能分析工具来发现问题,今天给大家分享一下小编最近使用的Profiler工具 帮助开发者了解应用的CPU,内存,网络

    2024年02月11日
    浏览(60)
  • 大批量数据导出csv,平替导出excel性能优化解决方案封装工具类

            有些业务逻辑需要在导出非常大量的数据,几百甚至几千万的数据这个时候再导出excel来对于性能都不是很友好,这个时候就需要替换实现思路来解决这个问题。         本文章提供了两种解决的方案,也是两种从数据库中拿取数据的方式一种是原生的jdbc一种是使用

    2024年01月16日
    浏览(73)
  • Android 开发必备知识点及面试题汇总(Android+Java+算法+性能优化+四大组件……),腾讯安卓开发面试

    5.请介绍下 AsyncTask的内部实现,适用的场景是 AsyncTask 内部也是 Handler 机制来完成的,只不过 Android 提供了执行框架来提供线程池来 执行相应地任务,因为线程池的大小问题,所以 AsyncTask 只应该用来执行耗时时间较短的任务, 比如 HTTP 请求,大规模的下载和数据库的更改不

    2024年04月15日
    浏览(65)
  • 前端开发怎么解决性能优化的问题? - 易智编译EaseEditing

    前端性能优化是确保网站或应用在加载速度、响应性和用户体验等方面达到最佳状态的关键任务。以下是一些解决前端性能优化问题的方法: 压缩和合并代码: 压缩和合并CSS、JavaScript和HTML文件可以减少文件大小,加快加载速度。使用压缩工具(如UglifyJS和CSSNano)和构建工具

    2024年02月11日
    浏览(47)
  • Redis缓存设计与性能优化【缓存和数据库不一致问题,解决方案:1.加过期时间这样可以一段时间后自动刷新 2.分布式的读写锁】

    在大并发下,同时操作数据库与缓存会存在数据不一致性问题 1、双写不一致情况 2、读写并发不一致 解决方案: 1、对于并发几率很小的数据(如个人维度的订单数据、用户数据等),这种几乎不用考虑这个问题,很少会发生缓存不一致, 可以给缓存数据加上过期时间,每隔一

    2024年04月13日
    浏览(54)
  • 腾讯云 Finops Crane 开发者集训营 - 云成本优化一站式解决方案实践

    一、 相关活动介绍: 自从上次参加完CSDN联合腾讯云发起的《云原生之降本增效》活动后,只是停留聚焦在优秀实践方法论、资源与弹性、架构设计上的了解,本次《腾讯云 Finops Crane 开发者集训营》是深入了解并实践基于 FinOps 框架开展的一个成本优化项目Crane。 活动相关链

    2024年02月12日
    浏览(48)
  • Android问题解决方案(一):Android 打空包提交开发者后台提示没有”android:exported“的属性设置

    今日了解到了一个新内容,意指打一个新的空包提审,来实现同个应用二次提审的效果;通过一系列操作后,成功打出了所谓aab格式的安装包。(至于为什么是aab格式,相信有所了解的朋友自然也知道什么原因,还未曾了解的朋友可以先了解相关的信息,这里就不赘述了,自

    2023年04月11日
    浏览(54)
  • Android 性能优化——APP启动优化

            首先在《Android系统和APP启动流程》中我们介绍了 APP 的启动流程,但都是 FW 层的流程,这里我们主要分析一下在 APP 中的启动流程。要了解 APP 层的启动流程,首先要了解 APP 启动的分类。 冷启动         应用从头开始启动,即应用的首次启动。需要做大量的工

    2024年04月12日
    浏览(47)
  • Android 性能优化系列:启动优化进阶

    应用的速度优化是我们使用最频繁,也是应用最重要的优化之一,它包括启动速度优化、页面打开速度优化、功能或业务执行速度优化等等,能够直接提升应用的用户体验。 大部分人谈到速度优化,只能想到一些零碎的优化点,比如使用多线程、预加载等等,没有一个较为体

    2024年02月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包