私はアンドロイドアプリを開発しています。私はそこにたくさんのビットマップを扱わなければなりません。場合によっては、メモリ不足のためにアプリがクラッシュすることがあります。ビットマップのリストを効率的に処理し、メモリ不足のエラーを回避する方法
私はカスタムオブジェクト(ソングクラス)を持っています。タイトル、アーティスト、リンク、ビットマップなどのフィールドがあります。オーディオストリームからアルバムのカバーを取得し、そのビットマップを関連するオブジェクトのフィールドに割り当てます。ここで
は、アルバムカバーのビットマップを取得するためのコード、
public static CustomBitmap downloadAudioCover(Context context, final String url) {
final MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
try {
metaRetriever.setDataSource(url, new HashMap<String, String>());
final byte[] art = metaRetriever.getEmbeddedPicture();
int width = context.getResources().getDimensionPixelSize(R.dimen.image_audio_cover_width);
int height = context.getResources().getDimensionPixelSize(R.dimen.image_audio_cover_height);
CustomBitmap customBitmap = new CustomBitmap();
customBitmap.setBitmap(decodeSampledBitmapFromResource(art, width, height));
return customBitmap;
} catch (Exception e) {
return null;
}
}
ここで私は、私は再び上記のプロセスを避けることができるように、オブジェクトをシリアル化してファイルに保存することCustomBitmapクラスを使用し、次回きていますユーザーは、アプリケーションのユーザーに来ると、遅滞なく、アルバムの表紙を見ることができます。
問題は約50曲あります。これは、50個のオブジェクトを50ビットマップで保持する必要があることを意味します。
このデータを表示するには、RecyclerViewを使用しています。
私は最初にビットマップを持っていないので、私はすべての単一の曲のために上記の方法を呼び出す必要があります。だから私は最初に(ビットマップなしで)曲を取得し、すべての曲をフェッチした後、私はビットマップを取得するために配列リストをループします。すべてのビットマップを取得したら、アダプタでnotifyDataSetChangedメソッドを呼び出します。
このプロセスでは、メモリがより多く消費されます。私は私のアプリでビットマップのこのリストを処理するためのより効率的な方法が必要です。任意の提案をいただければ幸いです。
*ビットマップをonBindViewHolderの中に入れて、これにオブジェクトを割り当てないでイメージビューに設定していますか?
ありがとうございました。
注:これはあなたがイメージをロードするためのライブラリを使用する必要があるビットマップ
private static Bitmap decodeSampledBitmapFromResource(byte[] arr, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(arr, 0, arr.length, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(arr, 0, arr.length, options);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height/2;
final int halfWidth = width/2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight/inSampleSize) >= reqHeight && (halfWidth/inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
[Glide](https://github.com/bumptech/glide)を試してみましたか? – Max
私はしていません。私は他の画像を読み込むためにこのアプリでユニバーサル画像ローダーを使用しています。しかし、あなたは、オーディオストリームからビットマップを取得し、setImageBitmapメソッドのみを使用してイメージビューに設定することがわかります。 – chathura
Facebookで[Fresco](https://github.com/facebook/fresco)画像読み込みライブラリを使用してください。すべてのイメージをリサイクルし、メモリをクリアすることで、すべてのOOMの問題を自動的に軽減します。私自身の経験では、UILは多くのOOMの問題を引き起こします。フレスコ画を使用すると、あなたは満足します:P –