2012-09-17 49 views
1

我有一个应用程序,它使用具有数千个图像的翻书风格动画。 APK的大小不是问题,因为它是一个内部唯一的应用程序,永远不会放在任何应用程序商店。如何在不分配内存的情况下使用ImageView

我遇到的问题是我的动画是一个子类ImageView的,在每秒15帧切换出来的图像,每次我打电话的时间setImageURI垃圾收集,然后运行。那么是否有另一种方法setImageURI不会导致垃圾收集运行?

编辑:多一点背景信息。

我的应用程序有12个序列,其中6个包含1609个图像,并且需要在特定帧处调用不同的事件。另一个需求是用户能够在任何帧上停下来调查情况并且执行一个动作或者继续下一个动作。 3D引擎本来就是理想的解决方案,但这种方法的提出是因为用户不需要完全的自由度,并且整个时间都处于“轨道”上。

这是应用程序的肉和那里的问题发生

try { 
    ((BitmapDrawable) getDrawable()).getBitmap().recycle(); 
    setImageURI(imgUri); 
    refreshDrawableState(); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 
+0

当您更改图像时,不需要在位图上调用回收。 ImageView为你做到了这一点。但问题是相同的。您正在失去对位图的引用,所以GC需要运行以收集它。防止这种情况发生的唯一方法是在ImageView外部保留对位图的引用,并在您有时间收集而无需用户注意时将其释放。 – DeeV

+0

@DeeV - 将它们保存在内存中是一个问题,因为我的约130mb jpgs扩展到每个2.7mb。以这种速度~190帧或13秒将通过更多的内存吃掉,而不是设备上的内存。 – Mytheral

+0

然后你有一个矛盾的问题,因为你需要内存继续,但你不能获得内存,除非你释放,但每次你释放一个位图,GC将运行。只要决定运行,GC就会运行。您对何时运行有限制。SoftReference建议可以通过仅在内存需要时取消分配而不是仅在GC决定该去时才解除分配。 您可以在绕过JVM的C++环境中分配位图,并且不会占用您的配额。尽管如此,你仍然受到硬件的限制。 – DeeV

回答

1

垃圾收集器正在运行,因为您正在交换一个映像用于另一个映像,它会转储上一个映像。每当您失去对图像的引用时都会发生。

这里有几种可能的方法来考虑。

  1. 既然你提到这是一个动画书,建立和分配AnimationDrawableImageView将作为一帧一帧的动画(动画书是什么)。这会一次加载所有图像,并将保留它们,直到您失去对AnimationDrawable的引用。

  2. 将所有图像存储为SoftReferences以缓存图像。 SoftReference会将对象保留在内存中,直到需要收集内存为止。这会减慢垃圾收集器的频率(假设这是原因)。使用BitmapFractory构建图像,使用setImageBitmap将其分配给ImageView。这样做的另一个好处是它允许您在将线程分配给ImageView之前在线程上构建图像。

+0

方法#2对我来说是“最好的”解决方案,因为简单的翻动书有点限制我停止/开始/从帧数x /恢复需要开始。 Android最终没有为我所需要的工作工作,因为无论我尝试什么,我的框架都变得很大,所以我切换到基于Windows的平板电脑。 – Mytheral

0

也许是因为你的图像需要多大的内存,和Android需要调用GB以释放更多MEM努力避免崩溃程序

相关问题