From 32fd0e79a2d380cbf391d2c9bbe8b120b1149237 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Tue, 29 Aug 2017 12:02:58 +0200 Subject: [PATCH] abstract WorkerHandler class, cleanup --- .../otaliastudios/cameraview/CameraView.java | 123 ++++++++---------- .../cameraview/WorkerHandler.java | 26 ++++ 2 files changed, 78 insertions(+), 71 deletions(-) create mode 100644 cameraview/src/main/utils/com/otaliastudios/cameraview/WorkerHandler.java diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 3d408dcf..e480e1da 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -1,7 +1,6 @@ package com.otaliastudios.cameraview; import android.Manifest; -import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; @@ -48,31 +47,20 @@ public class CameraView extends FrameLayout { private final static int DEFAULT_JPEG_QUALITY = 100; private final static boolean DEFAULT_CROP_OUTPUT = false; - private Handler mWorkerHandler; - - private Handler getWorkerHandler() { - synchronized (this) { - if (mWorkerHandler == null) { - HandlerThread workerThread = new HandlerThread("CameraViewWorker"); - workerThread.setDaemon(true); - workerThread.start(); - mWorkerHandler = new Handler(workerThread.getLooper()); - } - } - return mWorkerHandler; - } - - private void run(Runnable runnable) { - getWorkerHandler().post(runnable); - } - + // Self managed parameters private int mJpegQuality; private boolean mCropOutput; + private float mZoomValue; + private float mExposureCorrectionValue; + private HashMap mGestureMap = new HashMap<>(4); + + // Components private CameraCallbacks mCameraCallbacks; private OrientationHelper mOrientationHelper; private CameraController mCameraController; private Preview mPreviewImpl; + // Views private GridLinesLayout mGridLinesLayout; private PinchGestureLayout mPinchGestureLayout; private TapGestureLayout mTapGestureLayout; @@ -80,10 +68,9 @@ public class CameraView extends FrameLayout { private boolean mIsStarted; private boolean mKeepScreenOn; - private float mZoomValue; - private float mExposureCorrectionValue; - - private HashMap mGestureMap = new HashMap<>(4); + // Threading + private Handler mUiHandler; + private WorkerHandler mWorkerHandler; public CameraView(@NonNull Context context) { super(context, null); @@ -120,9 +107,14 @@ public class CameraView extends FrameLayout { GestureAction scrollVerticalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollVertical, GestureAction.DEFAULT_SCROLL_VERTICAL.value())); a.recycle(); + // Components mCameraCallbacks = new CameraCallbacks(); mPreviewImpl = new TextureViewPreview(context, this); mCameraController = new Camera1(mCameraCallbacks, mPreviewImpl); + mUiHandler = new Handler(Looper.getMainLooper()); + mWorkerHandler = new WorkerHandler("CameraViewWorker"); + + // Views mGridLinesLayout = new GridLinesLayout(context); mPinchGestureLayout = new PinchGestureLayout(context); mTapGestureLayout = new TapGestureLayout(context); @@ -134,11 +126,11 @@ public class CameraView extends FrameLayout { mIsStarted = false; - // Self managed + // Apply self managed setCropOutput(cropOutput); setJpegQuality(jpegQuality); - // Camera controller params + // Apply camera controller params setFacing(facing); setFlash(flash); setSessionType(sessionType); @@ -146,7 +138,7 @@ public class CameraView extends FrameLayout { setWhiteBalance(whiteBalance); setGrid(grid); - // Gestures + // Apply gestures mapGesture(Gesture.TAP, tapGesture); // mapGesture(Gesture.DOUBLE_TAP, doubleTapGesture); mapGesture(Gesture.LONG_TAP, longTapGesture); @@ -497,12 +489,7 @@ public class CameraView extends FrameLayout { if (checkPermissions(getSessionType())) { mIsStarted = true; - run(new Runnable() { - @Override - public void run() { - mCameraController.start(); - } - }); + mCameraController.start(); } } @@ -584,9 +571,8 @@ public class CameraView extends FrameLayout { } public void destroy() { + // TODO: this is not strictly needed mCameraCallbacks.clearListeners(); // Release inner listener. - // This might be useless, but no time to think about it now. - mWorkerHandler = null; } //endregion @@ -788,12 +774,7 @@ public class CameraView extends FrameLayout { * @param facing a facing value. */ public void setFacing(final Facing facing) { - run(new Runnable() { - @Override - public void run() { - mCameraController.setFacing(facing); - } - }); + mCameraController.setFacing(facing); } @@ -1214,18 +1195,13 @@ public class CameraView extends FrameLayout { class CameraCallbacks { - private ArrayList mListeners; - private Handler uiHandler; - + private ArrayList mListeners = new ArrayList<>(2); - CameraCallbacks() { - mListeners = new ArrayList<>(2); - uiHandler = new Handler(Looper.getMainLooper()); - } + CameraCallbacks() {} public void dispatchOnCameraOpened(final CameraOptions options) { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { @@ -1237,7 +1213,7 @@ public class CameraView extends FrameLayout { public void dispatchOnCameraClosed() { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { @@ -1253,7 +1229,7 @@ public class CameraView extends FrameLayout { // Request a layout pass for onMeasure() to do its stuff. // Potentially this will change CameraView size, which changes Surface size, // which triggers a new Preview size. But hopefully it will converge. - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { requestLayout(); @@ -1280,7 +1256,7 @@ public class CameraView extends FrameLayout { * because it was taken with the front camera. */ public void processImage(final byte[] jpeg, final boolean consistentWithView, final boolean flipHorizontally) { - getWorkerHandler().post(new Runnable() { + mWorkerHandler.post(new Runnable() { @Override public void run() { byte[] jpeg2 = jpeg; @@ -1300,25 +1276,30 @@ public class CameraView extends FrameLayout { } - public void processSnapshot(YuvImage yuv, boolean consistentWithView, boolean flipHorizontally) { - byte[] jpeg; - if (mCropOutput && mPreviewImpl.isCropping()) { - int w = consistentWithView ? getWidth() : getHeight(); - int h = consistentWithView ? getHeight() : getWidth(); - AspectRatio targetRatio = AspectRatio.of(w, h); - jpeg = CropHelper.cropToJpeg(yuv, targetRatio, mJpegQuality); - } else { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - yuv.compressToJpeg(new Rect(0, 0, yuv.getWidth(), yuv.getHeight()), mJpegQuality, out); - jpeg = out.toByteArray(); - } - dispatchOnPictureTaken(jpeg); + public void processSnapshot(final YuvImage yuv, final boolean consistentWithView, boolean flipHorizontally) { + mWorkerHandler.post(new Runnable() { + @Override + public void run() { + byte[] jpeg; + if (mCropOutput && mPreviewImpl.isCropping()) { + int w = consistentWithView ? getWidth() : getHeight(); + int h = consistentWithView ? getHeight() : getWidth(); + AspectRatio targetRatio = AspectRatio.of(w, h); + jpeg = CropHelper.cropToJpeg(yuv, targetRatio, mJpegQuality); + } else { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + yuv.compressToJpeg(new Rect(0, 0, yuv.getWidth(), yuv.getHeight()), mJpegQuality, out); + jpeg = out.toByteArray(); + } + dispatchOnPictureTaken(jpeg); + } + }); } private void dispatchOnPictureTaken(byte[] jpeg) { final byte[] data = jpeg; - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { @@ -1330,7 +1311,7 @@ public class CameraView extends FrameLayout { public void dispatchOnVideoTaken(final File video) { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { @@ -1342,7 +1323,7 @@ public class CameraView extends FrameLayout { public void dispatchOnFocusStart(@Nullable final Gesture gesture, final PointF point) { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { if (gesture != null && mGestureMap.get(gesture) == GestureAction.FOCUS_WITH_MARKER) { @@ -1359,7 +1340,7 @@ public class CameraView extends FrameLayout { public void dispatchOnFocusEnd(@Nullable final Gesture gesture, final boolean success, final PointF point) { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { if (success && mUseSounds) { @@ -1380,7 +1361,7 @@ public class CameraView extends FrameLayout { public void dispatchOnOrientationChanged(final int value) { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { @@ -1392,7 +1373,7 @@ public class CameraView extends FrameLayout { public void dispatchOnZoomChanged(final float newValue, final PointF[] fingers) { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { @@ -1406,7 +1387,7 @@ public class CameraView extends FrameLayout { public void dispatchOnExposureCorrectionChanged(final float newValue, final float[] bounds, final PointF[] fingers) { - uiHandler.post(new Runnable() { + mUiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { diff --git a/cameraview/src/main/utils/com/otaliastudios/cameraview/WorkerHandler.java b/cameraview/src/main/utils/com/otaliastudios/cameraview/WorkerHandler.java new file mode 100644 index 00000000..5b75660b --- /dev/null +++ b/cameraview/src/main/utils/com/otaliastudios/cameraview/WorkerHandler.java @@ -0,0 +1,26 @@ +package com.otaliastudios.cameraview; + +import android.os.Handler; +import android.os.HandlerThread; + +/** + * Class holding a background handler. + * Using setDaemon right now but a better approach would be to have + * start() and stop() callbacks here. TODO + */ +class WorkerHandler { + + private HandlerThread mThread; + private Handler mHandler; + + public WorkerHandler(String name) { + mThread = new HandlerThread(name); + mThread.setDaemon(true); + mThread.start(); + mHandler = new Handler(mThread.getLooper()); + } + + public void post(Runnable runnable) { + mHandler.post(runnable); + } +}