2016-06-25 9 views
0

まず、java.lang.OutOfMemoryErrorに関する質問を理解しています。ビットマップは以前に何度も尋ねられています。私もDisplaying Bitmaps Efficientlyページをチェックアウトしました。100文字列をバイト配列に変換するときのjava.lang.OutOfMemoryError

私のユースケース:

私はSQLiteのデータベースに文字列として二つの異なるサイズのビットマップを格納しています。ビットマップの最初のサイズは画面幅の50%で、第2サイズは画面幅の100%です。

私は、画像幅の50%または100%の画像を表示するRecyclerViewを使用しているため、ロードされているビットマップは、必要以上に大きくなく、イメージはデータベースから取得されます。

また、AsyncTaskを使用してビットマップをロードしています。

私はRecyclerViewに180以上のアイテムがありますので、360以上のビットマップ(numberOfimages * theDifferentSizesOfEachImage)が作成されています。私はこのコードを介して、バイト配列に画像の文字列バージョンをcoverting午前:byte [] byteArray = Base64.decode(encodedString, Base64.DEFAULT);

問題私はそれを再起動しない限り

活性は、java.lang.OutOfMemoryErrorをencurringことなく、170枚の異なる画像の周りにオーバーロードすることができましたアクティビティ(例えば、アクティビティを読み込んだり、ナビゲーション・ドロワを再度クリックしてアクティビティを再作成した後、そのプロセスを繰り返すなど)、文字列をバイト配列に変換するときにjava.lang.OutOfMemoryErrorが発生します。

私は、次のコードを使用してグライドライブラリ使用してビットマップにバイト配列に変換しています:私はjava.lang.OutOfMemoryErrorをしながら発生を避けるにはどうすればよい

Bitmap bitmap = Glide.with(context).load(byteArray).asBitmap() 
.dontTransform().dontAnimate().skipMemoryCache(true) 
.diskCacheStrategy(DiskCacheStrategy.NONE).into(-1, -1).get(); 

を一言で言えば

で私の質問を文字列をバイト配列に変換していますか?

私は与えられたビットマップ上のリサイクル()を呼び出していグライドを使用してビットマップを作成し、nullにそれを設定した後。

また、私はすでに、事前に私のAndroidのマニフェスト

おかげでandroid:largeHeap="true"

編集ここ

私はビットマップ文字列を作成していますどのようにされて使用しています:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     bitmap.compress(Bitmap.CompressFormat.WEBP,100, baos); 
     byte [] b =baos.toByteArray(); 
    String bitmapString = Base64.encodeToString(b, Base64.DEFAULT); 
+0

なぜあなたはそれを保存する前にそれを圧縮しないでください... –

+0

あなたの応答に感謝します。あなたがビットマップを圧縮することを言及しているなら、私はすでにそれをしています。自分の質問を編集し、ビットマップを圧縮してから文字列に変換する方法を確認できます。 –

+0

"SQLiteデータベースに2つの異なるサイズのビットマップを格納しています" - なぜ?それらをデータベースにファイル名でファイルとして保存します。または、BLOB列として格納して、少なくとも 'String'変換を排除します。 – CommonsWare

答えて

1

何私はあなたのアプローチを落とすことをお勧めします、これは画像の大きなセットでは機能しませんあなたはすでにあなたのスレッドで多くの作業をしています。 1つは、sqlliteにそのようなイメージを決して格納するべきではありません。 ビットマップを一意の名前を持つファイルに変換するか、または使用する場合に応じて同じにする必要があります。次に、このファイルをアプリケーションディレクトリに保存し、ファイルパスをデータベースに保存します。あなたに役立つコードがいくつかあります。

File pictureFile = getOutputMediaFile(getActivity(), MEDIA_TYPE_IMAGE); 
     if (pictureFile == null) { 
      return; 
     } 
     Bitmap bitmap =BitmapFactory.decodeByteArray(data,0,data.length); 

      FileOutputStream fos = new FileOutputStream(pictureFile); 
      bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); 
      fos.flush(); 
      fos.close(); 

プライベートファイルgetOutputMediaFile(コンテキストコンテキスト、int型メートル){

File mediaStorageDir = context.getFilesDir(); 

    if (!mediaStorageDir.exists()) { 
     if (!mediaStorageDir.mkdirs()) { 
      Log.d("Fade", "failed to create directory"); 
      return null; 
     } 
    } 
    // Create a media file name 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") 
      .format(new Date()); 

    File mediaFile=new File(mediaStorageDir.getPath()+File.separator 
       + "IMG_" + timeStamp + ".JPG"); 

    return mediaFile; 
} 

は今、あなたはファイルを持っているし、今はちょうど、データベース内のファイルのパスを格納することができますし、その必要なときにいつでも取得することができますグライドを使用してストレージからファイルを削除します。これにより、データベースがクエリに素早くなります。

この方法では、gradleや他の場所で変更する必要はありません。これを試して。

+0

ありがとうございます。 'java.lang.OutOfMemoryError'を解決するなら、ファイルをバイト配列として保存しようとします。イメージをファイルとして保存してイメージをイメージに変換すると、SQLIiteデータベースのBLOB列にイメージをバイト配列として保存し、それらのバイト配列をビットマップに変換するよりメモリが効率的だと思いますか? –

+0

はい、あなたはイメージにファイルを変換していません。ストレージに保存されたイメージ自体がファイルです。あなたは今、グライドライブラリにファイルの直接のパスを与え、非常に効率的であるグライドへのあなたの視点でのイメージのキャッシングと表示を残します。ちょうどそれを打ち、この解決策を常に実践してください。あなたが以前にしていたことはちょうど記憶の浪費です。アプリのフォルダ内にファイルとして画像を保存することで、ギャラリーが明らかになるので、あなたが望むように正しく動作します。 –

+0

情報ありがとうございます。イメージをファイルとして保存しようとします。そのイメージが 'java.lang.OutOfMemoryError'を解決すれば、私はあなたの答えを受け入れます –

関連する問題