关注Edittext的Android位图回收错误

时间:2014-05-25 13:29:13

标签: android bitmap imageview android-imageview android-bitmap

我有一个显示2 ImageViews的活动,其中一个被裁剪以适合一个正方形而第二个基于第一个正在进行并且正在CenterCropped以填充屏幕为背景图像有模糊。背景图像模糊过程发生在线程中。 在我说明该活动后,我试图通过ActivityForResult调用另一个活动,该活动有一个简单的对话框,例如带TextView的视图,确定和取消按钮。 如果我点击“确定/取消”按钮表示活动已完成并且一切正常,则当我尝试输入Edittext时出现问题,我收到错误Cannot draw recycled bitmap ,请注意我在另一项活动中!我认为它可能发生,因为键盘推动视图,所以我将活动设置为SoftPan仍然得到该消息。 如果我删除使背景模糊的部分,应用程序工作正常。 以下是一些代码:

此方法以jni处理图像,其大约3200px X 2400px(必须保持最高分辨率)

private void setImageViewResult()
{
    Bitmap b = BitmapFactory.decodeFile(image.getAbsolutePath());
    // store the bitmap in the JNI "world"
    final JniBitmapHolder bitmapHolder = new JniBitmapHolder(b);
    // no need for the bitmap on the java "world", since the operations are done on the JNI "world"
    b.recycle();
    // crop a center square from the bitmap, from (0.25,0.25) to (0.75,0.75) of the bitmap.
    // bitmapHolder.cropBitmap(width/4,height/4,width*3/4,height*3/4);
    // rotate the bitmap:
    bitmapHolder.rotateBitmapCw90();
    // get the output java bitmap , and free the one on the JNI "world"
    b = bitmapHolder.getBitmapAndFree();
    final int width = b.getWidth(), height = b.getHeight();
    // Bitmap b = ExifUtil.rotateBitmap(f.getAbsolutePath(), BitmapFactory.decodeFile(f.getAbsolutePath()));
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int screenWidth = size.x;
    int screenHeight = size.y;
    float boxSize = BOX_SIZE;// dpToPx(338);
    float boxCenterInScreenHeight = screenHeight / 2;
    float boxCenterInScreenWidth = screenWidth / 2;
    float boxYInScreen = boxCenterInScreenHeight - boxSize / 2;
    float boxXInScreen = boxCenterInScreenWidth - boxSize / 2;
    float boxHeightRatio = boxSize / screenHeight;
    float boxWidthRatio = boxSize / screenWidth;
    float yRatio = boxYInScreen / screenHeight;
    float xRatio = boxXInScreen / screenWidth;
    float CropFromY = b.getHeight() * yRatio;
    float CropFromX = b.getWidth() * xRatio;
    // float HeightAndWidthToCrop = b.getHeight() *
    // boxHeightRatio;
    float HeightAndWidthToCrop = b.getWidth() * boxWidthRatio;
    bitmapHolder.storeBitmap(b);
    b.recycle();
    bitmapHolder.cropBitmap((int) CropFromX, (int) CropFromY, (int) HeightAndWidthToCrop + (int) CropFromX, (int) HeightAndWidthToCrop + (int) CropFromY);
    bmp = bitmapHolder.getBitmapAndFree();
    ivResult.setImageBitmap(bmp);
    setBackgroundBlur();
}

模糊背景的方法:

private void setBackgroundBlur()
{
    Config.getThreadPool().submit(new Runnable()
    {
        @Override
        public void run()
        {
            // bgFile = StorageUtils.newTempFile("jpg");
            try
            {
                // WebExecutor.executeSync(new DownloadImage(item.getImageCoverUrl(), bgFile));
                Bitmap bmp2 = ImageUtils.createCenterCrop(bmp, new DimensionsRect((int) (Config.getScreenDimens().getWidth() / 2f),
                                                                                  (int) (Config.getScreenDimens().getHeight() / 2f)));
                bmp2 = ImageUtils.setGpuImageFilter(bmp2, new GPUImageSaturationFilter(1));
                Canvas c = new Canvas(bmp2);
                c.drawColor(0x77000000);
                bmp2 = ImageUtils.setGpuImageFilter(bmp2, new GPUImageBoxBlurFilter(1f));
                System.gc();
                bgBitmap = bmp2;
                handler.post(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        android.util.Log.i("SEB BACKGROUND BLUR", "in method");
                        Drawable d = new BitmapDrawable(bgBitmap);
                        // ivBackground.setImageBitmap(bgBitmap);
                        ((RelativeLayout) findViewById(R.id.toot)).setBackground(d);
                        ViewPropertyAnimator.animate(ivBackground).alpha(1).setDuration(500).start();
                    }
                });
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    });
}

OnCreate调用SetImageViewResult并启动第二个活动:

@Override
protected void onCreate(final Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rename_scan);
    setSoftPan();
    final EditText etName = (EditText) findViewById(R.popScan.name);
    final Button ok = (Button) findViewById(R.popScan.ok);
    final Button cancel = (Button) findViewById(R.popScan.cancel);
    ok.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(final View v)
        {}
    });
    cancel.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(final View v)
        {
            finish();
        }
    });
}

我尝试从setBackgroundBlur方法内部进行记录,以检查键盘打开后是否第二次调用它,但它没有。

logcat的:

05-25 16:51:49.913: E/AndroidRuntime(29258): FATAL EXCEPTION: main
05-25 16:51:49.913: E/AndroidRuntime(29258): java.lang.IllegalArgumentException: Cannot draw recycled bitmaps
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:789)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:118)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.widget.ImageView.onDraw(ImageView.java:985)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13719)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12657)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12701)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13435)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13722)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12657)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12701)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13435)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12655)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12701)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13435)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12655)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12701)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13435)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13722)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12657)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12701)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13435)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12655)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12701)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13435)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.draw(View.java:13722)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2473)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12657)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.View.getDisplayList(View.java:12701)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1198)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewRootImpl.draw(ViewRootImpl.java:2173)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2045)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1854)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.Choreographer.doFrame(Choreographer.java:532)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.os.Handler.handleCallback(Handler.java:725)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.os.Handler.dispatchMessage(Handler.java:92)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.os.Looper.loop(Looper.java:137)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at android.app.ActivityThread.main(ActivityThread.java:5227)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at java.lang.reflect.Method.invokeNative(Native Method)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at java.lang.reflect.Method.invoke(Method.java:511)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
05-25 16:51:49.913: E/AndroidRuntime(29258):    at dalvik.system.NativeStart.main(Native Method)
05-25 16:51:57.298: I/Process(29258): Sending signal. PID: 29258 SIG: 9
05-25 16:51:57.583: E/Trace(29333): error opening trace file: No such file or directory (2)
05-25 16:51:57.678: D/dalvikvm(29333): GC_EXPLICIT freed 172K, 78% free 2416K/10660K, paused 6ms+2ms, total 24ms
05-25 16:51:57.773: E/BitmapFactory(29333): Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.AppGate.mezuzot/cache/temp20140525_165145.jpg: open failed: ENOENT (No such file or directory)

1 个答案:

答案 0 :(得分:0)

这是导致异常的代码部分:

 b.recycle();

// get the output java bitmap , and free the one on the JNI "world"
b = bitmapHolder.getBitmapAndFree();

您无法将值重新分配给循环位图,因为它正在使用的内存已被释放。你必须重新编码。在你的情况下使用任何其他变量也应该正常工作。