3

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?

Vikalp Patel
  • 10,669
  • 6
  • 61
  • 96
Jumpa
  • 4,319
  • 11
  • 52
  • 100
  • does the camera have its necessary permission on AndroidManifest already? – bofredo Jul 24 '13 at 13:32
  • Please post the code in your onResume() method and also any related methods like initCamera() – user1132959 Jul 24 '13 at 13:33
  • To find out what it's waiting on, you should place log messages everywhere. This will allow you to see where the delay is and from there you can find out why. – user1132959 Jul 24 '13 at 13:35
  • Manifest is ok, onResume calls task execute (and nothing else), initCamera simply open (method) Camera. – Jumpa Jul 24 '13 at 14:26
  • Opening the camera may holds the UI Thread for an extended period of time on some devices. – type-a1pha Jul 24 '13 at 15:17
  • I know that, I just want to show the layout as a placeholder for the user, waiting the time necessary to the camera. – Jumpa Jul 24 '13 at 15:44

2 Answers2

2

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

Community
  • 1
  • 1
Jumpa
  • 4,319
  • 11
  • 52
  • 100
1

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.

type-a1pha
  • 1,891
  • 13
  • 19