2016-03-27 17 views
0

各行に画像があるListViewでAndroidアプリを作ろうとしています。私はすべての画像をBLOBデータ型のSQLiteデータベースに格納し、ListViewにこれらの画像を取り込みたいと思いますが、リストに2つ以上のJPEG画像がある場合は、OutOfMemoryErrorを取得します。私はすでに、メモリの使用を減らすためにインターネットで見つかった多くのテクニックを試しましたが、この問題を解決することはできません。私はoptions.inJustDecodeBoundsとoptions.inSampleSizeをアンドロイドのドキュメントで使用していますが、同じ例外が発生しています。私のコードは、ビットマップからバイト配列へ、バイト配列からビットマップへの変換で見つけることができます。Android Bitmap OutOfMemoryError in 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' '<アプリケーションアンドロイド:largeHeap =" true "> ...' –

+0

に同じエラーが発生しています – OrdinaryProgrammer

答えて

0

Androidには非常に不適切な画像メモリ管理機能があります。あなたは非常に注意深く画像を扱う必要があります。 Fortunatellyでは、外部ライブラリを使って画像表示を行うことができます。ユニバーサル画像ローダーで試してくださいUIL

0

イメージをSQLiteに保存しないでください。代わりにGlide/Picassoのような画像読み込み/キャッシングライブラリを使用すると、両方とも非常に使いやすく、画像をボックスからキャッシュすることができます。

1

ListViewで同じ問題が発生しました。私は、アクティビティを離れるときに割り当てられたメモリを解放することによってそれを解決しました。このため、私はdisplaydビットマップごとにメソッド "recycle()"を呼び出しました。

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(); 
}