Code Monkey home page Code Monkey logo

Comments (7)

android-dataticket avatar android-dataticket commented on May 11, 2024 2

try using these overrides to allow things to catch up before starting cameraview:

Thread delayThread0;
Thread delayThread1;

@Override
public void onResume() {
    super.onResume();
    if(getUserVisibleHint()) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                delayThread0 = Thread.currentThread();
                try {
                    delayThread0.sleep(500);
                    CameraActivity.this.cameraView.start();
                }catch(Exception e){
                    e.printStackTrace();
                }

            }
        }).start();
    }else{
        if(delayThread0 != null) {
            if (delayThread0.isAlive()) {
                delayThread0.interrupt();
            }
        }
        if(delayThread1 != null) {
            if (delayThread1.isAlive()) {
                delayThread1.interrupt();
            }
        }
        cameraView.stop();
    }
}

@Override
public void onPause() {
    if(delayThread0 != null) {
        if (delayThread0.isAlive()) {
            delayThread0.interrupt();
        }
    }
    if(delayThread1 != null) {
        if (delayThread1.isAlive()) {
            delayThread1.interrupt();
        }
    }
    cameraView.stop();
    super.onPause();
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(cameraView != null) {
        if (!isVisibleToUser) {
            if(delayThread0 != null) {
                if (delayThread0.isAlive()) {
                    delayThread0.interrupt();
                }
            }
            if(delayThread1 != null) {
                if (delayThread1.isAlive()) {
                    delayThread1.interrupt();
                }
            }
            cameraView.stop();
        }
        if (isVisibleToUser) {
            if(delayThread0 != null){
                if(!delayThread0.isAlive()){
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            delayThread1 = Thread.currentThread();
                            try {
                                delayThread1.sleep(500);
                                CameraActivity.this.cameraView.start();
                            }catch(Exception e){
                                e.printStackTrace();
                            }

                        }
                    }).start();
                }else{
                    //let thread 0 start camera
                }
            }else{
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        delayThread1 = Thread.currentThread();
                        try {
                            delayThread1.sleep(500);
                            CameraActivity.this.cameraView.start();
                        }catch(Exception e){
                            e.printStackTrace();
                        }

                    }
                }).start();
            }

        }
    }
}

from camerakit-android.

ZivKaputa avatar ZivKaputa commented on May 11, 2024 1

Upon further inspection, I believe the issue is a result of the TextureView's inconsistent callback time.

Shortly after being created, a TextureView executes the callback function onSurfaceTextureAvailable(), which, in this case, calls dispatchSurfaceChanged() and onSurfaceChanged() in the parent PreviewImpl object.

The onSurfaceChanged callback method for the PreviewImpl object is defined in Camera1.java, as seen below:

preview.setCallback(new PreviewImpl.Callback() {
            @Override
            public void onSurfaceChanged() {
                
                if (mCamera != null) {
                    
                    setupPreview();
                    adjustCameraParameters();
                }
            }
        });

The Exception arises because the method adjustCameraParameters() can also be called from the openCamera() ( which is called from the start() method ):

private void openCamera() {
        if (mCamera != null) {
            releaseCamera();
        }
        
        mCamera = Camera.open(mCameraId);
        mCameraParameters = mCamera.getParameters();

        adjustCameraParameters();
        mCamera.setDisplayOrientation(
                calculateCameraRotation(mDisplayOrientation)
        );

        mCameraListener.onCameraOpened();
    }

When adjustCameraParameters() is run in the PreviewImpl's callback method, the code runs on the main thread, since the object "preview" is originally created on the main thread in the CameraView constructor.

However, when adjustCameraParameters() is run in openCamera(), it is run on a background thread, since CameraView's start method runs mCameraImpl.start() in a new thread ( As seen below )

public void start() {

        ...

        new Thread(new Runnable() {
            @Override
            public void run() {
               
                mCameraImpl.start();

            }
        }).start();
    }

In most cases, this causes no problems. If the onSurfaceChanged() callback is called before CameraView.start() is called, then the (mCamera != null) condition in the callback is false since the camera has not been initialized, and nothing occurs. Furthermore, if onSurfaceChanged() is called after the mCameraImpl.start() method ends, then setupPreview() and adjustCameraParameters() on the background thread do not conflict with code on the main thread ( since the adjustment code has already finished running ).

However, in the specific case that the callback is fired while the adjustCameraParameters() method in the background thread has just started, the (mCamera != null) condition will be true, since mCamera is initialized in the openCamera() method before adjustCameraParameters() ( See openCamera() code block above ). As a result, adjustCameraParameters() will begin to run on the main thread as well as the background thread — which, as mentioned in the comment above, causes various types of exceptions.

As mentioned in Issue #49, running mCameraImpl.start() on the main thread instead of a new thread should solve this problem.

from camerakit-android.

ZivKaputa avatar ZivKaputa commented on May 11, 2024

Does this occur when you startup the activity containing the camera and/or around the time you call CameraView.start()? If so, you may want to look at a similar issue that has been marked as closed (#49).

The issue likely has something to do with threading in the CameraView class. Both CameraView.start() and CameraView.setFacing() are called on new threads, and in certain circumstances ( when CameraView.start() is called shortly after the CameraView constructor is called ), two instances of the same methods may be running at once. This could cause various types of modification errors, including ConcurrentModificationException and NullPointerException.

from camerakit-android.

JakeWoki avatar JakeWoki commented on May 11, 2024

Device: Honor 8 Lite
OS: EMUI5.0(Android 7.0)

from camerakit-android.

Xittery avatar Xittery commented on May 11, 2024

From where do you get getUserVisibleHint?

from camerakit-android.

dwillmc avatar dwillmc commented on May 11, 2024

This should be fixed now with the latest release. Can you update your build.gradle to reference com.wonderkiln:camerakit:0.11.1. If the issue persists can you please re-open.

Thanks!

from camerakit-android.

 avatar commented on May 11, 2024

This issue still exists even in version 0.12.0

from camerakit-android.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.