我的平板电脑应用程序必须显示一个非常大的图像 (2500x6000) 并允许用户平移、放大和缩小。由于它无法放入内存中,因此我将其分解为图块并根据需要加载它们。我遇到的问题是,每当我卸载或替换位图时,我都会导致垃圾收集,从而使我的应用程序因明显的口吃而暂停。我想知道是否有人想出了任何巧妙的方法来解决这个问题?我使用 BitmapFactory.decodeResource 创建我的位图。我尝试替换相同的位图,但垃圾收集仍在运行(假设它转储旧位图并用新位图替换它)。
谢谢!
想出了答案!在 API11+ BitmapFactory.Options 中有一个名为 inBitmap 的属性,它将在加载内容时重用位图。我已经这样实现了:
mBg[i] = Bitmap.createBitmap(800, 1232, Bitmap.Config.RGB_565);
mBgOptions[i] = new BitmapFactory.Options();
mBgOptions[i].inBitmap = mBg[i];
mBgOptions[i].inPreferredConfig = Bitmap.Config.RGB_565;
mBgOptions[i].inMutable = true;
mBgOptions[i].inSampleSize = 1;
垃圾收集器不再运行,暂停已被删除。作为参考,必须设置 inSampleSize 否则它将不起作用。
你在使用 android:largeHeap="true" 吗?这可能会降低 GC 的频率。此外,鉴于您的目标是平板电脑,那么您可以放心地假设您正在处理并发垃圾收集器。因此,如果它有更多、更小的内存块要收集,即更小的块,它将工作得最好。
如果您的目标是 Android 3.0,那么这个答案可能会有所帮助:
在 Android 3.0 之前,您可以构建平铺图像的 HTML 页面,并让内置浏览器处理图像的加载和卸载。我在这里的回答有更多细节:
还有其他人有其他方法吗?
我使用了这个易于整合的 WorldMap 应用程序源:
https://github.com/johnnylambada/WorldMap
这使用了世界地图的巨大图像,并使用缓存来显示地图。
为了整合,我只是复制了所有的 java 文件(我猜是 5 个)并在我的布局文件中使用了 surfaceView。然后我通过了 ImageViewerActivity.java 的小 OnCreate() 方法,并在我的活动中使用了代码(略有改动,取决于我个人的使用)。