2016-10-07 41 views
3

所以我在Crashlytics看到我們有很多崩潰是由OOM和位圖引起的。 似乎其中60%來自6.0.1上的Galaxy S7 Edge設備。 我們擁有的是具有2個圖像的着陸屏幕,從右向左滾動的背景圖像,然後被重新創建,以給他們移動到前景圖像的印象。Andom OOM with Bitmap

在布料日誌的頂部,它顯示了膨脹類的錯誤。 然而,在堆棧中,我發現它似乎是由我們的ParallaxImageView引起的。 在這裏我們這樣做:

private void initializeCustomAttrs(Context context, AttributeSet attrs) { 
    TypedArray attributes = context.getTheme().obtainStyledAttributes(
      attrs, 
      R.styleable.ParallaxImageView, 
      0, 0); 

    try { 
     speed = attributes.getDimension(R.styleable.ParallaxImageView_speed, 10); 
     bitmap = BitmapFactory.decodeResource(getContext().getResources(), 
       attributes.getResourceId(R.styleable.ParallaxImageView_src, 0)); 

    } finally { 
     attributes.recycle(); 
    } 
} 

我不知道這是否是正確的它發生在哪裏,或者如果其他方法可能會導致此。 我們也有這些方法:

@Override 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    if (canvas == null || bitmap == null) { 
     return; 
    } 

    canvas.getClipBounds(clipBounds); 

    while (offset <= -bitmap.getWidth()) { 
     offset += bitmap.getWidth(); 
    } 

    float left = offset; 
    while (left < clipBounds.width()) { 
     int width = bitmap.getWidth(); 
     canvas.drawBitmap(bitmap, getBitmapLeft(width, left), 0, null); 
     left += width; 
    } 

    if (isAnimating && speed != 0) { 
     offset -= abs(speed); 
     postInvalidateOnAnimation(); 
    } 
} 

@Override 
public void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
    start(); 
} 

@Override 
public void start() { 
    if (!isAnimating) { 
     isAnimating = true; 
     postInvalidateOnAnimation(); 
    } 
} 

@Override 
public void stop() { 
    if (isAnimating) { 
     isAnimating = false; 
     invalidate(); 
    } 
} 

private Bitmap scaleToFitHeight(Bitmap bitmap, int height) { 
    if (height > 0) { 
     float factor = height/(float) bitmap.getHeight(); 

     Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * factor), height, true); 
     if (!newBitmap.equals(bitmap)) { 
      bitmap.recycle(); 
     } 

     return newBitmap; 
    } 
    return bitmap; 
} 

private float getBitmapLeft(float layerWidth, float left) { 
    if (speed < 0) { 
     return clipBounds.width() - layerWidth - left; 
    } else { 
     return left; 
    } 
} 

我不知道,因爲我認爲我們正在解碼並正確回收這可能是導致這個問題。不知道是否它可能是6.0.1上的東西造成它,但任何幫助在這裏將不勝感激。 謝謝

+0

你也可以發佈日誌嗎? – petey

回答

0

你沒有正確解碼圖像,你應該首先檢查大小,然後用比例因子解碼。假設您的映像是2000 x 2000,壓縮版本可能很容易爲< 1mb,但將其解壓縮爲位圖需要2000 * 2000 * 4字節= 16mb(!)
如果您確信圖像不是這種情況大小是可管理的,但既然你得到OOM我想這不是

查看here的實施細節