多数の画像に非常に迅速にアクセスする必要があるアプリがあるため、これらの画像を何らかの方法でメモリにロードする必要があります。ビットマップが 100 MB を超える RAM を使用するため、これはまったく問題外でした。そのため、jpg ファイルをメモリに読み込み、byteArray 内に格納することにしました。次に、それらをデコードし、必要に応じてキャンバスに書き込みます。これは非常にうまく機能し、メモリ制限を尊重しながら、遅いディスク アクセスを排除します。
ただし、メモリ使用量は「オフ」のようです。それぞれ約 33kb のファイル サイズで 450 の jpg を保存しています。これは合計で約 15MB のデータです。ただし、Eclipse DDMS と Android (物理デバイス上) の両方で報告されているように、アプリは 35MB から 40MB の RAM で継続的に実行されます。読み込まれる jpg の数を変更してみましたが、アプリが使用する RAM は jpg あたり約 60 ~ 70kb 減少する傾向があり、各画像が RAM に 2 回保存されることを示しています。メモリ使用量は変動しません。これは、実際の「リーク」が関係していないことを意味します。
関連する読み込みコードは次のとおりです。
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 に jpg を格納するのに、それだけのオーバーヘッドが関係しているのでしょうか?