我应该使用哪种方法以获得更好的性能,Nine-Patch 还是 Drawable XML 资源?

11
什么是为视图设置背景的最佳方法?例如,两种不同的背景样式:
1.渐变、圆角和边框的背景 2.单色和圆角的背景
那么哪一种方式更好,使用九宫格图片(nine-patch)还是可绘制的xml资源(drawable xml resource)?

1
我不知道!:) 但是由于标准的Android主题经常使用9patch,所以我认为这样做应该不会太错。 - pumpkee
我的意思是,如果我只需要单一颜色的背景,使用XML资源会更快吗?至少XML文件的大小会更小。 - cooperok
如果您只需要一种颜色,请使用该颜色设置背景。无需图像资源,也无需XML配置。 - MengMeng
但是,如果我需要圆角呢? - cooperok
1个回答

17

我的猜测是,在大多数情况下,NinePatch 会稍微快一些。以下是我发现的。

GradientDrawable(用于xml中的矩形)使用此代码调用Canvas,然后使用原生调用导致SkCanvasSkDraw,最终是SkScanSkBlitter

另一方面,NinePatch 的 draw() 在调用本地NinePatch.cpp之前几乎没有Java代码,该文件又调用NinePatchImpl.cpp -- NinePatch_draw(),这就是魔法所在。代码在这里迭代标记的区域,并在许多后续调用之后使用与SkDraw相同的逻辑(只有drawRect()而不是drawPath())绘制内容,但最终完成工作的仍然是相同的SkScanSkBlitter

所有的代码对我来说都很难立即理解,但我注意到的是,如果背景和描边都存在,GradientDrawable 会向整个本机堆栈进行两次调用 (看这里),而在任何情况下,NinePatch 只会进行一次调用。
因此,在没有实际测量两种方法的时间的情况下,我感觉在大多数情况下,NinePatch 会赢得这场比赛:如果我们 [极其] 粗略地假设 drawRect()drawPath() 的本机函数调用堆栈使用的逻辑基本相同,并且 [另一个极其简化的假设] 在那里传递并由 NinePatchGradientDrawable 创建的参数集对方法的复杂性影响不是很大,那么 NinePatch 填充和轮廓的速度大约是 GradientDrawable 的两倍快。当然,前提是您使用常规的 9 段 9-Patch(即不要通过大量标记使您的 9-Patch 被撕裂,从而使对部分的迭代过程过于费力)。 任何碰巧看到这篇文章并了解更多相关主题(和/或更擅长估计本机代码复杂性)的人,请纠正我。 PS 是的,我知道这不是一个直接的答案

干得好,谢谢你的回答。这几乎是我想听到的。你向我展示了一个好的例子,让我深入源代码中寻找答案 :) - cooperok
其实,我正在编辑答案,发现我忽略了一些东西,所以我正在删除一些论点 :) 但据我所知,结果是一样的——NinePatches 获胜。 - Ivan Bartsov
3
简单来说:准备好的像素数据和使用额外 CPU 循环生成的像素数据。这在计算机图形学中也是通用的。 - S.D.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接