2016-03-27 2 views
0

Я пытаюсь сделать приложение Android с ListView, у которого есть изображение в каждой строке. Я хочу сохранить все изображения в базе данных SQLite с типом данных BLOB, а затем заполнить ListView этими изображениями, но всякий раз, когда у меня есть более двух изображений jpeg в списке, я получаю OutOfMemoryError. Я уже пробовал много методов, найденных в Интернете, чтобы уменьшить использование памяти, но все еще не может решить эту проблему. Я нашел использование options.inJustDecodeBounds и options.inSampleSize в документации по Android, но все равно получаю то же исключение. Ниже вы можете найти мой код с Bitmap для байтового массива и массива байтов для преобразования растрового изображения.Android Bitmap OutOfMemoryError в ListView

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 


public class ListItem { 

private int id; 
private byte [] img; 
private String title; 
private String description; 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public byte[] getImg() { 
    return img; 
} 

public void setImg(byte[] img) { 
    this.img = img; 
} 

public String getTitle() { 
    return title; 
} 

public void setTitle(String title) { 
    this.title = title; 
} 

public String getDescription() { 
    return description; 
} 

public void setDescription(String description) { 
    this.description = description; 
} 

public static byte[] convertBitmapToBytes(Bitmap bmp){ 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream); 
    byte[] byteArray = stream.toByteArray(); 
    return byteArray; 
} 

public static Bitmap getBitmap(byte [] bitmapdata){ 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    ByteArrayInputStream inStream = new ByteArrayInputStream(bitmapdata); 
    BitmapFactory.decodeStream(inStream, null, options); 
    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, 50, 50); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    Bitmap bmp = BitmapFactory.decodeStream(inStream,null,options); 
    return bmp; 
} 

public 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

попытка установить в '' Manifest.xml' <приложение для Android: largeHeap = "истинный"> ... ' –

+0

все еще получаю ту же ошибку – OrdinaryProgrammer

ответ

0

У Android очень плохое управление памятью изображений. поэтому вам нужно быть очень осторожным обращением с изображениями. Удачно вы можете попробовать с внешней библиотекой позаботиться о отображении изображения. Попробуйте использовать универсальный загрузчик изображений UIL

0

Вы не должны хранить изображения в SQLite. Вместо этого используйте библиотеку загрузки/кэширования изображений, такую ​​как Glide/Picasso, оба из них чрезвычайно просты в использовании и кэшируют изображения из коробки.

1

У меня такая же проблема в ListView. Я решил это, освободив выделенную память при выходе из нее. Для этого я назвал метод «recycle()» для каждого растрового изображения displayd.

private List<Bitmap> m_displayedBitmaps = new ArrayList<Bitmap>(); 

private List<ImageView> m_displayedGridElements = new ArrayList<ImageView>(); 

// protected void onPause() { 
public void onStop() { 

    // don't forget to free the references to your bitmap 
    for (ImageView currentGridElement : m_displayedGridElements) { 
     currentGridElement.setImageBitmap(null); 
    } 
    m_displayedGridElements.clear(); 

    // recycle each image 
    for (Bitmap currentBitmap : m_displayedBitmaps) { 
     currentBitmap.recycle(); 
    } 
    // clear the list 
    m_displayedBitmaps.clear(); 



    super.onStop(); 
} 
Смежные вопросы