我有一个应用程序需要非常快速地访问大量图像,因此我需要以某种方式将这些图像加载到内存中。这样做是因为位图使用了超过 100MB 的 RAM,这完全不可能,所以我选择将 jpg 文件读入内存,将它们存储在 byteArray 中。然后我将它们解码并根据需要将它们写入画布。这工作得很好,减少了缓慢的磁盘访问,同时也尊重内存限制。
但是,内存使用对我来说似乎“关闭”。我存储了 450 个 jpg,每个文件大小约为 33kb。总共大约 15MB 的数据。但是,正如 Eclipse DDMS 和 Android(在物理设备上)报告的那样,该应用程序持续在 35MB 到 40MB 的 RAM 上运行。我尝试修改加载的 jpg 数量,并且应用程序使用的 RAM 每张 jpg 会减少大约 60-70kb,这表明每个图像在 RAM 中存储了两次。内存使用量没有波动,这意味着没有涉及实际的“泄漏”。
这是相关的加载代码:
private byte[][] bitmapArray = new byte[totalFrames][];
for (int x=0; x<totalFrames; x++) {
File file = null;
if (cWidth <= cHeight){
file = new File(directory + "/f"+x+".jpg");
} else {
file = new File(directory + "/f"+x+"-land.jpg");
}
bitmapArray[x] = getBytesFromFile(file);
imagesLoaded = x + 1;
}
public byte[] getBytesFromFile(File file) {
byte[] bytes = null;
try {
InputStream is = new FileInputStream(file);
long length = file.length();
bytes = new byte[(int) length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file " + file.getName());
}
is.close();
} catch (IOException e) {
//TODO Write your catch method here
}
return bytes;
}
最终,它们会像这样被写入屏幕:
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
int canvasWidth = c.getWidth();
int canvasHeight = c.getHeight();
Rect destinationRect = new Rect();
destinationRect.set(0, 0, canvasWidth, canvasHeight);
c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[bgcycle], 0, bitmapArray[bgcycle].length), null, destinationRect, null);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
我是否正确,这里发生了某种重复?或者像这样在 byteArray 中存储 jpgs 是否有那么多开销?