3

几天来,我一直试图让一个非常大的画布工作。

将所有内容添加到画布后,画布的宽度有时为 30,000,但如果将此代码添加到 ondraw 方法,水平滚动会变得非常慢。

然后我尝试将所有内容添加到位图中,然后在 onDraw 方法中绘制位图。虽然这适用于较小的位图,但对于 30,000 宽的位图,我遇到了内存不足错误。

任何人都可以提出解决方案,我不确定现在要尝试什么。

谢谢

编辑我也尝试将位图更改为 Config.RGB_565,但仍然出现内存错误。

4

4 回答 4

5

处理大型 Canvas 将不断遇到 OutOfMemoryExceptions。画布写入位图,像 30,000 x X 位图之类的东西会占用大量内存。我认为您最好的选择是跟踪可见屏幕相对于您要显示的位置的位置,并且只将需要的内容写入画布。

例如,如果用户向下和向左滚动 100 像素,那么对于 1024 x 768 的显示,在画布上绘制将在 30,000 x 30,000 的虚拟画布中显示在 1124 和 868 处的内容(您不会全部绘制) )。

于 2012-10-23T01:40:02.247 回答
1

您的 ArrayList 中有多少条目,它似乎很大。

据我了解,在 onDraw() 中绘制所有内容没有 OoM 问题,但它真的很慢吗?如果是这种情况,最可能的原因是您正在调用大量的drawText,这非常慢,基本上如果您有 10000 个字符串要绘制,系统将不得不测量它们中的每一个,以便仅确定给定的字符串在你的大画布上是否可见,然后实际的绘图部分也很慢。

您可以测试绘制所有文本所花费的时间,看看是否是这种情况。

如果确实如此,那么最简单的方法是将每个字符/数字映射到位图,您可以让艺术家创建 PNG 文件,或者在onCreate(Bundle)或其他一些名为-once-per-Activity-creation 方法,将位图放在 String-to-Bitmap HashMap 中,而不是调用

canvas.drawText(bellNumber, xPad, mOriginY, paint); 

你打电话给类似的东西

canvas.drawBitmap(hash.get(bellNumber), src, dst, paint); //remember to reuse src & dst

这将完全绕过与字符串相关的绘图开销,并且应该使您的 onDraw 操作更快一些。

于 2012-10-27T16:46:43.800 回答
1

位图的大小取决于设备,但通常取决于特定设备的大小。此外,位图是为基于 sdk 的应用程序创建内存泄漏的主要方式之一。你最好的选择是将你的画布分成更小的部分,或者考虑其他选项,例如在 openGL 中渲染画布(这也有大小限制,但通常会渲染得更快)。

于 2012-10-29T05:08:29.487 回答
0

Flynn81 总体上给出了一个很好的答案。查看您的行逻辑,我会做一些数学运算并尝试预测需要绘制哪些行。由于您正在处理文本,因此您可以获得字体度量(测量文本)。由于您似乎在处理数字,因此您可以尝试测量字符串的高度,例如“0123456789”。

您可能想要对此进行分析,但您可能能够缓存线条图。

如果你真的很勇敢,你可以尝试使用 ListView 和自定义可绘制类型

于 2012-10-31T13:16:54.130 回答