2016-11-03 93 views
0

加載自定義圖像時出現內存不足錯誤。我讀https://developer.android.com/training/displaying-bitmaps/load-bitmap.html尋求幫助。有效加載位圖 - 仍然出現內存不足錯誤

我按照這個例子來解碼流來獲取大小信息,然後解碼。第一次解碼仍然崩潰。有沒有解決的辦法?

ava.lang.OutOfMemoryError:無法分配與16776928個空閒字節和25MB一個48771084字節分配直到OOM BackgroundImageManager.java,線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,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

要處理bitmpas您可以使用現有的許多開源庫之一。 E.g 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))); 

應該

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

選擇的對象必須是該方法的調用的一部分才能使用。

0

更好的管理圖像的方法是使用畢加索圖書館,因爲它管理緩存和內存,並因此避免了OutOfMemory崩潰。

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

此處瞭解詳情: Picasso library

+0

@an_android_dev我將不得不打開一個輸入流,或者我可以強制使用Uri.parse(bgUri),而不是 「YOUR_URL」? – quantumpotato

+0

@quantumpotato你可以使用url字符串。例如:load(「http://example.com/myimage.jpeg」); –

+0

@an_android_dev我會試試這個。我擁有的URI是本地設備 – quantumpotato

相關問題