From c816f569f4a528a1e68e08a5484dc1a22bf01c40 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Wed, 16 Oct 2019 18:03:00 +0200 Subject: [PATCH] Use CopyOnWriteArrayList for Camera2 action list. Fixes #649 --- .../cameraview/engine/Camera2Engine.java | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index a35de766..71420ed3 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -70,6 +70,7 @@ import com.otaliastudios.cameraview.video.SnapshotVideoRecorder; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; @RequiresApi(Build.VERSION_CODES.LOLLIPOP) @@ -111,7 +112,8 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv private final boolean mPictureCaptureStopsPreview = false; // can be configurable at some point // Actions - private final List mActions = new ArrayList<>(); + // Use COW to properly synchronize the list. We'll iterate much more than mutate + private final List mActions = new CopyOnWriteArrayList<>(); private MeterAction mMeterAction; public Camera2Engine(Callback callback) { @@ -1428,28 +1430,14 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv @Override public void addAction(final @NonNull Action action) { - // This is likely to be called during a Capture callback while we iterate - // on the actions list, or worse, from other threads. We must use mHandler.post. - mHandler.post(new Runnable() { - @Override - public void run() { - if (!mActions.contains(action)) { - mActions.add(action); - } - } - }); + if (!mActions.contains(action)) { + mActions.add(action); + } } @Override public void removeAction(final @NonNull Action action) { - // This is likely to be called during a Capture callback while we iterate - // on the actions list, or worse, from other threads. We must use mHandler.post. - mHandler.post(new Runnable() { - @Override - public void run() { - mActions.remove(action); - } - }); + mActions.remove(action); } @NonNull