【问题标题】:Using PNGs for Animation on Android在 Android 上使用 PNG 制作动画
【发布时间】:2017-01-14 21:55:34
【问题描述】:

我听说对动画使用位图列表是个坏主意。但是直到现在我还没有遇到证明这是真的情况。

我的代码效果很好。但只能在模拟器上,或者在我运行 Android 6 的手机上。任何低于此值的东西,我都会在它完成初始化之前得到内存不足。

这就是我加载图像的方式:

public static Image[] flameIs = new Image[300];


for (int i=0;i<300;i++) {
    if (i>=10) framePref="000";
    if (i>=100) framePref="00";
    Assets.flameIs[i] = g.newImage("frames/lighter_" + framePref +i+ ".png", ImageFormat.RGB565);
}

所以它就像 300 个 PNG,8 位,每个大小约为 12k。我们说的是小于 4MB 的图像。

应用程序稍后所做的就是永远在循环中运行这些帧。

有没有办法避免“内存不足”?

【问题讨论】:

  • 位图的平均尺寸是多少?
  • 都是459x620
  • 那么每个图像需要 284,580 字节来将未压缩的数据存储在内存中(459 x 620 x 8 位)。堆上 81 MB 的 300 张图像。
  • 那么您最初的建议是更紧密地裁剪图像吗?有很多可以裁剪的黑色空间。
  • 你用这些图片做什么?

标签: android performance


【解决方案1】:

300 个 459x620 的位图加载为 RGB_565 意味着您需要 300 * 459*620 * 2 = 171 MB 的内存。

查看https://stackoverflow.com/a/9940415/3413324 总结了流行设备的堆大小,我们可以看到即使对于最近的设备,您的位图也可能超过限制。

你可以做的是:

  • 减小位图的大小,以便它们每个都需要更少的内存空间

  • 减少用于动画的位图数量,从而减少内存占用

  • 使用可以通过库加载的 GIF。然后,您可以直接控制唯一 GIF 文件的大小

  • 如果可能,以编程方式创建动画

【讨论】:

  • 你现在得到 +1。我会试试这个。我特别喜欢你链接的内存堆列表。我会回到这个。
  • 我不知道如何以编程方式创建“动画”。这本质上是作为帧缓冲区运行的单个活动,即重绘的恒定状态。意思是,它只是循环运行并刷新整个屏幕。这就是为什么我使用一个数组来保存下一帧,等等......
  • 当您的场景由几组四处移动的图像组成时,以编程方式创建动画可能会导致巨大的内存增益。即:如果您只需要通过代码移动它们而不是加载动画的每一帧,那么只需要 10 个对象(位图)来移动的动画将占用更少的内存。虽然并不总是可能的,但记住它总是好的
  • 我接受了这个答案,因为您建议减小图像大小是最好的解决方案。我将它们中的所有 300 个裁剪为 306x509,这实际上将堆分配减少了一半。该应用程序现在支持最早的 Android 4.4。
【解决方案2】:

与其创建一个 300 帧的动画,为什么不直接将它们转换成 GIF 并使用 Glide 之类的东西来渲染呢? (如果您不想在项目中添加新库,甚至可以使用 webview)

它将为您提供更好的跨平台控制和可移植性。

使用 Glide,它看起来像这样:

ImageView imageView = (ImageView) findViewById(R.id.imageView); GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imageView); Glide.with(this).load(R.raw.sample_gif).into(imageViewTarget);

【讨论】:

  • 如果这个程序是使用 XML 编写为一个活动,这将是一个选项。但按照目前的编写方式,它会不断地重绘页面。意思是,GIF 不会持续存在。不过,这是一个好主意。
猜你喜欢
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多