2016-11-03 4 views
0

カスタムイメージを読み込む際にメモリエラーが発生しました。私はhttps://developer.android.com/training/displaying-bitmaps/load-bitmap.htmlを読んで助けます。ビットマップを効率的に読み込んでもメモリエラーが発生する

まず、ストリームをデコードしてサイズ情報を取得し、デコードする例を示します。その最初のデコードではまだクラッシュしています。これを回避する方法はありますか?

ava.lang.OutOfMemoryError:OOM BackgroundImageManager.javaまで16776928の空きバイトと25メガバイトと48771084バイトの割り当ての割り当てに失敗しました、ライン84

dalvik.system.VMRuntime.newNonMovableArrayネイティブメソッド 2 android.graphics .BitmapFactory.nativeDecodeStreamネイティブメソッド 3 android.graphics.BitmapFactory.decodeStreamInternal BitmapFactory.java、ライン882 4 android.graphics.BitmapFactory.decodeStream BitmapFactory.java、ライン858 5 android.graphics.BitmapFactory.decodeStream BitmapFactory.java、ライン896 6 com.myapp.Utils.BackgroundImageManager.background Ba ckgroundImageManager.java、あなたが利用できる多くのオープンソースライブラリのいずれかを使用することができますbitmpasを処理するために、ライン8

public class BackgroundImageManager { 
    private final static String TAG = BackgroundImageManager.class.getSimpleName(); 
    private static InputStream currentBackgroundImage; 

    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; 
      } 
     } 
     Log.v("Biscuit-Sample", String.valueOf(inSampleSize)); 
     if (inSampleSize < 4) { 
      inSampleSize = 4; 
     } 
     return inSampleSize; 
    } 

    public static Drawable background(Context context, Store store) { 
     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 

     String bgUri = null; 
     int bgId = 0; 
     if (store != null) { 
      bgUri = store.backgroundImageURI; 
      bgId = store.backgroundImageNumber; 
     } 

     if (currentBackgroundImage != null) { 
      try { 
       currentBackgroundImage.close(); 
       Log.v(TAG, "Current background image closed."); 
      } catch (IOException e) { 
       Log.e(TAG, "Could not close background image.", e); 
      } 
     } 

     if(bgUri != null && !bgUri.isEmpty()) { 
      try { 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inJustDecodeBounds = true; 

       Activity activity = (Activity) context; 
       Display display = activity.getWindowManager().getDefaultDisplay(); 
       Point size = new Point(); 
       display.getSize(size); 
       int width = size.x; 
       int height = size.y; 
       BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(bgUri))); 
       options.inSampleSize = BackgroundImageManager.calculateInSampleSize(options, width, height); 
       Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(bgUri))); 
       Drawable d = new BitmapDrawable(context.getResources(), bitmap); 
       return d; 
      } catch (FileNotFoundException e) { 
       Log.e(TAG, "Custom background image file could not be found.", e); 
      } catch (IOException e) { 
       Log.e(TAG, "Could not close custom background image after creating drawable", e); 
      } 
     } 
     if(bgId != 0) { 
      try { 
       return context.getResources().getDrawable(bgId); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     return context.getResources().getDrawable(R.drawable.bg_default); 
    } 

答えて

1

。例えば、あなたの問題へFresco

:あなたは二度同じビットマップをデコードしている

まず。

BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(bgUri))); 
options.inSampleSize = BackgroundImageManager.calculateInSampleSize(options, width, height); 
Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(bgUri))); 

コピー/貼り付けが間違っている可能性があります。最初の行では、ビットマップはデコードされ、使用されません。最初BitmapFactory.decodeStream

削除問題は、それが

Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(bgUri)), null, options); 

オプションのオブジェクトが順番に使用されるメソッドの呼び出しの一部である必要がありますする必要があり、ここで

Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(bgUri))); 

あります。

0

イメージを管理する方が良い方法は、キャッシュとラムを管理しているため、Picasaのライブラリであるため、OutOfMemoryのクラッシュを回避できます。

例:ここPicasso.with(Context).load("your_url").into(yourImageView);

さらに詳しい情報: Picasso library

+0

@an_android_dev私は、入力ストリームを開く必要があります、または私が代わりに "your_url" のUri.parse(bgUri)を使用JUSことができますか? – quantumpotato

+0

@quantumpotatoあなたはURL文字列を使うことができます。例:load( "http://example.com/myimage.jpeg"); –

+0

@an_android_devこれを試してみます。私が持っているURIはデバイスのローカルです – quantumpotato

関連する問題