#android #performance #android-bitmap
#Android #Производительность #android-bitmap
Вопрос:
Я разрабатываю приложение для Android, и мне приходится иметь дело с большим количеством растровых изображений там. Иногда приложение вылетает из-за нехватки памяти.
Итак, у меня есть пользовательский объект (класс песни), и там у меня есть такие поля, как название, исполнитель, ссылка и растровое изображение. Я получаю обложку альбома из аудиопотока и назначаю это растровое изображение в поле соответствующего объекта.
Вот код для получения растрового изображения обложки альбома,
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 amp;amp; (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
Комментарии:
1. вы пробовали Glide ?
2. У меня нет. Я использую универсальный загрузчик изображений в этом приложении для загрузки других изображений. но, как вы можете видеть, я получаю растровое изображение из аудиопотока и устанавливаю его в imageview, используя только метод setImageBitmap.
3. Используйте библиотеку загрузки изображений Fresco Facebook. Это автоматически устраняет все проблемы с ООМ, перерабатывая все изображения и очищая память самостоятельно. По моему собственному опыту, UIL вызывает множество проблем с ООМ. Используйте Fresco, и вы будете счастливы: P
Ответ №1:
Вам нужно использовать библиотеку для загрузки изображений.
Glide — потрясающая библиотека для загрузки изображений.
Прежде всего, зависимость
поместите эти два в свой build.gradle
compile 'com.github.bumptech.glide:glide:3.7.0'
и затем в вашем адаптере, куда вы загружаете изображение, все, что вам нужно сделать, это:
Glide
.with(context)
.load(AudioArt)
.into(yourImageView);
Вы также можете настроить его в соответствии со своими потребностями, просто посетите их страницу на Github.
У Future Studio также есть отличное руководство по его настройке.
Комментарии:
1. получает ли растровое изображение аудиопоток?? я не думаю??
2. Это так. Переменная AudioArt может быть
byte[]
. Удачи!)