Jumpa
Jumpa

Reputation: 4419

AsyncTask Open Camera

I've an activity that uses full screen SurfaceHolder, opening camera for preview (based on zxing code).

Starting this activity results slow (1.x second), I think because of the heavy lifting of the camera manager. I'm using onResume method; is it a good idea to move the code inside an AsyncTask?

I'd like to immediately render the layout and then wait for the camera (i think it's a better user experience). How can i handle this?

Activity

private class CameraTask extends AsyncTask<Void, Void, Void> {
    SurfaceHolder.Callback callback;

    public CameraTask(SurfaceHolder.Callback callback) {
        this.callback = callback;
    }
    protected void doInBackground() {
        cameraManager = new CameraManager(getApplication());
        viewfinderView = (ViewFinderView) findViewById(R.id.viewfinder_view);
        viewfinderView.setCameraManager(cameraManager);
        SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
        SurfaceHolder surfaceHolder = surfaceView.getHolder();

        if (hasSurface) {
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(callback);
        }
    }
}

This code has no errors, but layout rendering still wait for camera opening. I'm calling execute method of AsyncTask in onResume, is it the correct location?

Upvotes: 3

Views: 3816

Answers (2)

Jumpa
Jumpa

Reputation: 4419

Solution found here: Show my Layout while SurfaceView is loading Camera Preview. Basically, add SurfaceView programatically and not inside your xml layout.

Upvotes: 1

type-a1pha
type-a1pha

Reputation: 1893

Here's your answer (caution part):

http://developer.android.com/reference/android/hardware/Camera.html#open%28int%29

Note that it is not as simple as it may seems and as suggested in other answers since the AsyncTask may not run immediately. So consider this: you start the AsyncTask, then the context is switched to the main thread that calls onPause(), thus not calling release since the reference to the camera is null. But now the AsyncThread starts executing again opening the camera. Now you have a paused Activity that still holds an open Camera object. Everything that doesn't involve:

  • joining the AsyncTask as some point

  • or using some synchronization method

  • or running operations on camera sequentially

may lead to race conditions, errors (like when calling camera methods on a not-opened camera) and resource leakage.

Upvotes: 1

Related Questions