Android Curv Gradient 曲线渐层2-优化篇

前言

延续前篇Android Curv Gradient 曲线渐层
过了一个月...终于改好啦!!!!

效率比较

机型:同样使用Oppo R17 Pro
绘製数量:190个
监控工具:FPS监测工具 wasabeef/Takt
监控工具这边说明一下,前篇有提到在这样的测试条件下会有明显的卡顿问题,因此想到最直观的检测结果应该就是用FPS吧,但实际开发一开始是使用AndroidProfiler,监控记忆体以及物件的状况,大概类似下面这样,可以从记忆体走势、物件创建状况为参考,逐一去排除可能造成卡顿的问题。
http://img2.58codes.com/2024/20126774vcilFa6Q9Z.png

首先我做一个一基準,先全部用TextView观察整个使用状况(由于这边不支援Gif,有兴趣请点外部连结出去看)
操作过程
生成RecyclerView FPS:2.3
快速滑动FPS:22.6 ~ 60
除了一看开使生成RecyclerView有些微卡顿,在使用中感觉不出卡顿

接下来使用旧版的也就是前篇未优化的版本
生成RecyclerView FPS:7.5
快速滑动FPS:2.6 ~ 7.5
操作过程

优化版
生成RecyclerView FPS:1.3
快速滑动FPS:17.2 ~ 51.3
操作过程

从数据部分可以看到在按下Load钮,生成RecyclerView即便用完全原生的TextView也是会有明显的卡顿状况,但是为何使用旧版的相比起来反而FPS比较高,我后来又测试了多次,三个版本大约都落在10FPS内,所以就不多探究这个部分。
快速滑动过程应该不用看数据就可以感觉到旧版有明显的卡顿,FPS部分也确实有明显的落差。

实际优化方案

发想

初期也是看了Profiler里面,会产生大量的物件,特别是Point, LinearGradient。Point改用两组Integer完全没有改善,LinearGradient又省不了,本来重複使用LinearGradient,至于mPositions参数的变化用反射的方式修改,但没试出来。一气之下就打算用改用JNI试试,主要是过去有个经验,把一模一样逻辑从Java搬到C直接快3倍,虽然有点麻烦但直觉肯定会变快。

实作

由于主要是要解决大量Java物件产生的问题,因此就只有在Java层取的一些基本设定,还有UI尺寸之后就直接送到C去计算以及渲染。计算部分流程都相同,主要差别在于LinearGradient直线渲染部分必须要自行解决

以下程式码是从原始码native-lib.cpp里面撷取,有兴趣请直接到Github查看

将从Java传过来的int color转为RGB

int* color0 = new int[3];color0[0] = *tmpColor >> 16 & 0xff;color0[1] = *tmpColor >> 8 & 0xff;color0[2] = *tmpColor & 0xff;
//整张图的尺寸int* tmpArray = new int[width * height];for(int j = 0; j < width; j++) {    //渐变点的座标    int centerPosition = ((float) height)  * fullPositions[j];    for (int i = 0; i < height; i++) {        int red, green, blue;        //计算每个Pixel颜色        if(i < centerPosition) {            float ratio = (float)i / (float)centerPosition;            red = color0[0] + ((float)(color1[0] - color0[0]) * ratio);            green = color0[1] + ((float)(color1[1] - color0[1]) * ratio);            blue = color0[2] + ((float)(color1[2] - color0[2]) * ratio);        }        else{            int secondHalf = height - centerPosition;            float ratio = (float)(i - centerPosition) / (float)secondHalf;            red = color1[0] + ((float)(color2[0] - color1[0]) * ratio);            green = color1[1] + ((float)(color2[1] - color1[1]) * ratio);            blue = color1[2] + ((float)(color2[2] - color1[2]) * ratio);        }        tmpArray[i * width + j] = 255 << 24 | (red << 16) | (green << 8) | blue;    }}

透过上面的程式码已经将所有Pixel的颜色都填好了,接下来就是回到Java的部分产生Bitmap并且绘製就完成了

Bitmap bmp = Bitmap.createBitmap(tmpArray, width, height, Bitmap.Config.ARGB_8888);canvas.drawBitmap(bmp, 0, 0, paint);

结论

优化部分大致做到这个阶段,用起来还算顺畅了,由于平常没什么机会写C,程式码应该还有很大的优化空间,但制哨初步的目的达到了,有空再来改写


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章