1

I would like to first reference this question. I am having the same issue and this question was never resolved. The suggested solution does not work and I am completely stumped.

Any help would be greatly appreciated.

The exception is thrown when I attempt to make a layout change to the current activity specifically on okButton.setVisibility(View.VISIBLE), I'm convinced that this is a Thread issue:

@Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.i(TAG, "Saving a bitmap to file");
        Toast.makeText(context,"Not Starting New Activity. Look at me now error!",Toast.LENGTH_LONG).show();;
        //attempt to export all this to JavaCameraView, i have a feeling that there is a conflict with his thread....maybe that will help
        buttonManager(data);

    }

    private void buttonManager(byte[] data) {
        //find buttons
        final byte[] img_data = data;
        final int width = this.getWidth();
        final int height = this.getHeight();

        okButton.setVisibility(View.VISIBLE);
        retryButton.setVisibility(View.VISIBLE);
        captureImageButton.setVisibility(View.GONE);


        okButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent startImgProc = new Intent(context,ImageProcessing.class);
                startImgProc.putExtra("image",img_data);
                startImgProc.putExtra("width",width);
                startImgProc.putExtra("height",height);
                disconnectCamera();
                context.startActivity(startImgProc);
                ((Activity) context).finish();
            }
        });

        retryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                captureImageButton.setVisibility(View.VISIBLE);
                okButton.setVisibility(View.GONE);
                retryButton.setVisibility(View.GONE);
            }
        });
    }

The relevant canvas related code:

protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
    Mat modified;

    if (mListener != null) {
        modified = mListener.onCameraFrame(frame);
    } else {
        modified = frame.rgba();
    }

    boolean bmpValid = true;
    if (modified != null) {
        try {
            Utils.matToBitmap(modified, mCacheBitmap);
        } catch(Exception e) {
            Log.e(TAG, "Mat type: " + modified);
            Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight());
            Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
            bmpValid = false;
        }
    }

    if (bmpValid && mCacheBitmap != null) {

            Canvas canvas = getHolder().lockCanvas();
            if (canvas != null) {
                canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
                Log.d(TAG, "mStretch value: " + mScale);

                if (mScale != 0) {
                    canvas.drawBitmap(mCacheBitmap, new Rect(0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
                            new Rect((int) ((canvas.getWidth() - mScale * mCacheBitmap.getWidth()) / 2),
                                    (int) ((canvas.getHeight() - mScale * mCacheBitmap.getHeight()) / 2),
                                    (int) ((canvas.getWidth() - mScale * mCacheBitmap.getWidth()) / 2 + mScale * mCacheBitmap.getWidth()),
                                    (int) ((canvas.getHeight() - mScale * mCacheBitmap.getHeight()) / 2 + mScale * mCacheBitmap.getHeight())), null);
                } else {
                    canvas.drawBitmap(mCacheBitmap, new Rect(0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
                            new Rect((canvas.getWidth() - mCacheBitmap.getWidth()) / 2,
                                    (canvas.getHeight() - mCacheBitmap.getHeight()) / 2,
                                    (canvas.getWidth() - mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth(),
                                    (canvas.getHeight() - mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight()), null);
                }

                if (mFpsMeter != null) {
                    mFpsMeter.measure();
                    mFpsMeter.draw(canvas, 20, 30);
                }
                getHolder().unlockCanvasAndPost(canvas);
            }
        }

this is the code with the thread that operates the above code

private class CameraWorker implements Runnable {

        @Override
        public void run() {
            do {
                boolean hasFrame = false;
                synchronized (JavaCameraView.this) {
                    try {
                        while (!mCameraFrameReady && !mStopThread) {
                            JavaCameraView.this.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (mCameraFrameReady)
                    {
                        mChainIdx = 1 - mChainIdx;
                        mCameraFrameReady = false;
                        hasFrame = true;
                    }
                }

                if (!mStopThread && hasFrame) {
                    if (!mFrameChain[1 - mChainIdx].empty())
                        deliverAndDrawFrame(mCameraFrame[1 - mChainIdx]);
                }
            } while (!mStopThread);
            Log.d(TAG, "Finish processing thread");
        }
    }

and the stacktrace

E/SurfaceHolder: Exception locking surface
                 java.lang.IllegalArgumentException
                     at android.view.Surface.nativeLockCanvas(Native Method)
                     at android.view.Surface.lockCanvas(Surface.java:267)
                     at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:973)
                     at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:941)
                     at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:405)
                     at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:308)
                     at java.lang.Thread.run(Thread.java:818)
ClimbingTheCurve
  • 323
  • 2
  • 14
  • Did you try this?: https://stackoverflow.com/questions/26987728/java-lang-illegalargumentexceptionat-android-view-surface-unlockcanvasandpostn Not the same, but a similar error. – Carcigenicate Aug 29 '18 at 12:04
  • I wish it were that simple. I'm afraid it doesn't make a difference. – ClimbingTheCurve Aug 29 '18 at 12:59
  • Can anyone help? I am at my wits end with this :( – ClimbingTheCurve Aug 29 '18 at 20:14
  • The problem is, I couldn't even look up the source to see what leads to that being thrown. That method just delegates to the native method `nativeLockCanvas`, which afaik means the compiler implements it. It also isn't documented well anywhere what causes that exception to be thrown. The only thing I could find were forum posts of people with the same problem. – Carcigenicate Aug 29 '18 at 21:33
  • It's hard to say if this is possible without seeing more code, but is it possible that the `lock` is called, then an exception is thrown and the `unlock` is never called, then `lock` is being called again? Apparently trying to lock an already locked canvas can cause this. – Carcigenicate Aug 29 '18 at 21:36
  • I appreciate your help. I'll see if I can do something with that informarion. My instinct is that something isn't being released properly because this problem started when I implemented a call to start a new activity that has a button for returning to the original activity. – ClimbingTheCurve Aug 30 '18 at 04:25

0 Answers0