2016-05-06 218 views
0

我正在使用this library來模糊我的佈局在android下面的區域。 當越來越模糊視圖被調用時,我越來越stackoverflowerror和活動崩潰。請幫忙。 謝謝。java.lang.StackOverflowError:堆棧大小8MB

這裏是logcat的

BlurringView活動

import android.content.Context; 
import android.content.res.Resources; 
import android.content.res.TypedArray; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.drawable.ColorDrawable; 
import android.support.v8.renderscript.Allocation; 
import android.support.v8.renderscript.Element; 
import android.support.v8.renderscript.RenderScript; 
import android.support.v8.renderscript.ScriptIntrinsicBlur; 
import android.util.AttributeSet; 
import android.view.View; 

/** 
* A custom view for presenting a dynamically blurred version of another view's content. 
* <p/> 
* Use {@link #setBlurredView(android.view.View)} to set up the reference to the view to be blurred. 
* After that, call {@link #invalidate()} to trigger blurring whenever necessary. 
*/ 
public class BlurringView extends View { 

    public BlurringView(Context context) { 
     this(context, null); 
    } 

    public BlurringView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     final Resources res = getResources(); 
     final int defaultBlurRadius = res.getInteger(R.integer.default_blur_radius); 
     final int defaultDownsampleFactor = res.getInteger(R.integer.default_downsample_factor); 
     final int defaultOverlayColor = res.getColor(R.color.default_overlay_color); 

     initializeRenderScript(context); 

     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PxBlurringView); 
     setBlurRadius(a.getInt(R.styleable.PxBlurringView_blurRadius, defaultBlurRadius)); 
     setDownsampleFactor(a.getInt(R.styleable.PxBlurringView_downsampleFactor, 
       defaultDownsampleFactor)); 
     setOverlayColor(a.getColor(R.styleable.PxBlurringView_overlayColor, defaultOverlayColor)); 
     a.recycle(); 
    } 

    public void setBlurredView(View blurredView) { 
     mBlurredView = blurredView; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     if (mBlurredView != null) { 
      if (prepare()) { 
       // If the background of the blurred view is a color drawable, we use it to clear 
       // the blurring canvas, which ensures that edges of the child views are blurred 
       // as well; otherwise we clear the blurring canvas with a transparent color. 
       if (mBlurredView.getBackground() != null && mBlurredView.getBackground() instanceof ColorDrawable) { 
        mBitmapToBlur.eraseColor(((ColorDrawable) mBlurredView.getBackground()).getColor()); 
       } else { 
        mBitmapToBlur.eraseColor(Color.TRANSPARENT); 
       } 

       mBlurredView.draw(mBlurringCanvas); 
       blur(); 
       mBlurredView.invalidate(); 

       canvas.save(); 
       canvas.translate(mBlurredView.getX() - getX(), mBlurredView.getY() - getY()); 
       canvas.scale(mDownsampleFactor, mDownsampleFactor); 
       canvas.drawBitmap(mBlurredBitmap, 0, 0, null); 
       canvas.restore(); 
      } 
      canvas.drawColor(mOverlayColor); 
     } 
    } 

    public void setBlurRadius(int radius) { 
     mBlurScript.setRadius(radius); 
    } 

    public void setDownsampleFactor(int factor) { 
     if (factor <= 0) { 
      throw new IllegalArgumentException("Downsample factor must be greater than 0."); 
     } 

     if (mDownsampleFactor != factor) { 
      mDownsampleFactor = factor; 
      mDownsampleFactorChanged = true; 
     } 
    } 

    public void setOverlayColor(int color) { 
     mOverlayColor = color; 
    } 

    private void initializeRenderScript(Context context) { 
     mRenderScript = RenderScript.create(context); 
     mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript)); 
    } 

    protected boolean prepare() { 
     final int width = mBlurredView.getWidth(); 
     final int height = mBlurredView.getHeight(); 

     if (mBlurringCanvas == null || mDownsampleFactorChanged 
       || mBlurredViewWidth != width || mBlurredViewHeight != height) { 
      mDownsampleFactorChanged = false; 

      mBlurredViewWidth = width; 
      mBlurredViewHeight = height; 

      int scaledWidth = width/mDownsampleFactor; 
      int scaledHeight = height/mDownsampleFactor; 

      // The following manipulation is to avoid some RenderScript artifacts at the edge. 
      scaledWidth = scaledWidth - scaledWidth % 4 + 4; 
      scaledHeight = scaledHeight - scaledHeight % 4 + 4; 

      if (mBlurredBitmap == null 
        || mBlurredBitmap.getWidth() != scaledWidth 
        || mBlurredBitmap.getHeight() != scaledHeight) { 
       mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight, 
         Bitmap.Config.ARGB_8888); 
       if (mBitmapToBlur == null) { 
        return false; 
       } 

       mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, 
         Bitmap.Config.ARGB_8888); 
       if (mBlurredBitmap == null) { 
        return false; 
       } 
      } 

      mBlurringCanvas = new Canvas(mBitmapToBlur); 
      mBlurringCanvas.scale(1f/mDownsampleFactor, 1f/mDownsampleFactor); 
      mBlurInput = Allocation.createFromBitmap(mRenderScript, mBitmapToBlur, 
        Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); 
      mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType()); 
     } 
     return true; 
    } 

    protected void blur() { 
     mBlurInput.copyFrom(mBitmapToBlur); 
     mBlurScript.setInput(mBlurInput); 
     mBlurScript.forEach(mBlurOutput); 
     mBlurOutput.copyTo(mBlurredBitmap); 
    } 

    @Override 
    protected void onDetachedFromWindow() { 
     super.onDetachedFromWindow(); 
     if (mRenderScript != null) { 
      mRenderScript.destroy(); 
     } 
    } 

    private int mDownsampleFactor; 
    private int mOverlayColor; 

    private View mBlurredView; 
    private int mBlurredViewWidth, mBlurredViewHeight; 

    private boolean mDownsampleFactorChanged; 
    private Bitmap mBitmapToBlur, mBlurredBitmap; 
    private Canvas mBlurringCanvas; 
    private RenderScript mRenderScript; 
    private ScriptIntrinsicBlur mBlurScript; 
    private Allocation mBlurInput, mBlurOutput; 

    } 

MyActivity類

的代碼

logcat的錯誤

E/AndroidRuntime: FATAL EXCEPTION: main 
Process: com.example.user.designsample, PID: 19998 
java.lang.StackOverflowError: stack size 8MB 
at android.graphics.Canvas.drawOval(Canvas.java:1155) 
at android.graphics.Canvas.drawOval(Canvas.java:1147) 
at android.graphics.drawable.GradientDrawable.draw(GradientDrawable.java:615) 
at android.view.View.drawBackground(View.java:16376) 
at android.view.View.draw(View.java:16175) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundredpx.android.blur.BlurringView.onDraw(BlurringView.java:65) 
at android.view.View.draw(View.java:16184) 
at com.fivehundred 
05-05 23:16:31.323 19998-19998/com.example.user.humandesignsample E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 
6333780) 
05-05 23:16:31.361 19998-19998/com.example.user.humandesignsample   E/AndroidRuntime: Error reporting crash 
android.os.TransactionTooLargeException: data parcel size 6333780 bytes 
at android.os.BinderProxy.transactNative(Native Method) 
at android.os.BinderProxy.transact(Binder.java:503) 
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4425) 
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:90) 
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) 
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690) 
+0

顯然BlurringView不能模糊本身... – Selvin

回答

2

嘗試這樣

blurringView.setBlurredView(the_view_which_you_want_to_blur); 

就是這樣

3

的問題肯定是這一行:

blurringView.setBlurredView(blurringView); 

你分配BlurringView本身。這沒有任何意義。我想(我不想讀整個BlurringView類),setBlurredView用於你想模糊的View。而BlurringView將作爲blur覆蓋。因此,將blur覆蓋層分配爲"blurred"根本沒有任何意義。