我正在开发一个Android应用程序,我必须在那里处理很多位图。有时应用程序因内存不足而崩溃。
所以我有一个自定义对象(Song类),我有像标题,艺术家,链接和位图这样的字段。我从音频流中获取专辑封面,并将该位图分配到相关对象的字段中。
以下是获取专辑封面位图的代码
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中获取位图并设置为imageview而不为对象分配一个好的解决方案吗?
感谢。
注意:这是采样位图的代码
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;
}
答案 0 :(得分:1)
您需要使用库来加载图像。
Glide是一个用于加载图像的神奇库。
首先,依赖是
将这两个放在build.gradle中
compile 'com.github.bumptech.glide:glide:3.7.0'
然后在您的适配器中,您需要加载图像:
Glide
.with(context)
.load(AudioArt)
.into(yourImageView);
您也可以根据自己的需要进一步定制,只需访问他们的Github Page。
Future Studio也有很好的自定义教程。