Improved the CameraThread state machine, and fixed a bug where preview would not continue after capture.

git-svn-id: https://zxing.googlecode.com/svn/trunk@353 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
dswitkin 2008-04-08 16:06:13 +00:00
parent e9ed806d30
commit d9fc77b9e2

View file

@ -34,8 +34,14 @@ final class CameraThread extends Thread {
private final CameraSurfaceView surfaceView; private final CameraSurfaceView surfaceView;
private final Handler activityHandler; private final Handler activityHandler;
private final DecodeThread decodeThread; private final DecodeThread decodeThread;
private boolean requestDecode; private State state;
private boolean suspendPreview;
private enum State {
PREVIEW,
DECODE,
SAVE,
DONE
}
CameraThread(BarcodeReaderCaptureActivity activity, CameraSurfaceView surfaceView, CameraThread(BarcodeReaderCaptureActivity activity, CameraSurfaceView surfaceView,
CameraManager cameraManager, Handler activityHandler) { CameraManager cameraManager, Handler activityHandler) {
@ -44,8 +50,7 @@ final class CameraThread extends Thread {
decodeThread = new DecodeThread(activity, cameraManager); decodeThread = new DecodeThread(activity, cameraManager);
decodeThread.start(); decodeThread.start();
requestDecode = true; state = State.DONE;
suspendPreview = false;
} }
@Override @Override
@ -55,37 +60,38 @@ final class CameraThread extends Thread {
public void handleMessage(Message message) { public void handleMessage(Message message) {
switch (message.what) { switch (message.what) {
case R.id.preview: case R.id.preview:
if (!suspendPreview) { if (state == State.PREVIEW) {
surfaceView.capturePreviewAndDraw(); surfaceView.capturePreviewAndDraw();
} }
break; break;
case R.id.save: case R.id.save:
suspendPreview = true; state = State.SAVE;
Message save = Message.obtain(decodeThread.handler, R.id.save); Message save = Message.obtain(decodeThread.handler, R.id.save);
save.sendToTarget(); save.sendToTarget();
break; break;
case R.id.restart_preview: case R.id.restart_preview:
restartPreviewAndDecode(); restartPreviewAndDecode();
return; break;
case R.id.quit: case R.id.quit:
state = State.DONE;
Message quit = Message.obtain(decodeThread.handler, R.id.quit); Message quit = Message.obtain(decodeThread.handler, R.id.quit);
quit.sendToTarget(); quit.sendToTarget();
Looper.myLooper().quit(); Looper.myLooper().quit();
break; break;
case R.id.decode_started: case R.id.decode_started:
// Since the decoder is done with the camera, continue fetching preview frames. // Since the decoder is done with the camera, continue fetching preview frames.
suspendPreview = false; state = State.PREVIEW;
break; break;
case R.id.decode_succeeded: case R.id.decode_succeeded:
state = State.DONE;
// Message.copyFrom() did not work as expected, hence this workaround. // Message.copyFrom() did not work as expected, hence this workaround.
Message success = Message.obtain(activityHandler, R.id.decode_succeeded, message.obj); Message success = Message.obtain(activityHandler, R.id.decode_succeeded, message.obj);
success.arg1 = message.arg1; success.arg1 = message.arg1;
success.sendToTarget(); success.sendToTarget();
suspendPreview = true;
break; break;
case R.id.decode_failed: case R.id.decode_failed:
// We're decoding as fast as possible, so when one fails, start another. // We're decoding as fast as possible, so when one fails, start another.
requestDecode = true; startDecode();
break; break;
case R.id.save_succeeded: case R.id.save_succeeded:
// TODO: Put up a non-blocking status message // TODO: Put up a non-blocking status message
@ -94,15 +100,10 @@ final class CameraThread extends Thread {
case R.id.save_failed: case R.id.save_failed:
// TODO: Put up a blocking error message // TODO: Put up a blocking error message
restartPreviewAndDecode(); restartPreviewAndDecode();
return; break;
} }
if (requestDecode) { if (state == State.PREVIEW) {
requestDecode = false;
suspendPreview = true;
Message decode = Message.obtain(decodeThread.handler, R.id.decode);
decode.sendToTarget();
} else if (!suspendPreview) {
Message preview = Message.obtain(handler, R.id.preview); Message preview = Message.obtain(handler, R.id.preview);
preview.sendToTarget(); preview.sendToTarget();
} }
@ -111,8 +112,7 @@ final class CameraThread extends Thread {
decodeThread.setCameraThreadHandler(handler); decodeThread.setCameraThreadHandler(handler);
// Start ourselves capturing previews // Start ourselves capturing previews
Message preview = Message.obtain(handler, R.id.preview); restartPreviewAndDecode();
preview.sendToTarget();
Looper.loop(); Looper.loop();
} }
@ -131,14 +131,24 @@ final class CameraThread extends Thread {
message.sendToTarget(); message.sendToTarget();
} }
/**
* Start a decode if possible, but not now if the DecodeThread is in the middle of saving.
*/
private void startDecode() {
if (state != State.SAVE) {
state = State.DECODE;
Message decode = Message.obtain(decodeThread.handler, R.id.decode);
decode.sendToTarget();
}
}
/** /**
* Take one preview to update the screen, then do a decode and continue previews. * Take one preview to update the screen, then do a decode and continue previews.
*/ */
private void restartPreviewAndDecode() { private void restartPreviewAndDecode() {
requestDecode = true; state = State.PREVIEW;
suspendPreview = false; surfaceView.capturePreviewAndDraw();
Message preview = Message.obtain(handler, R.id.preview); startDecode();
preview.sendToTarget();
} }
} }