Use CopyOnWriteArrayList for Camera2 action list. Fixes #649

pull/651/head
Mattia Iavarone 6 years ago
parent 063c7a76fb
commit c816f569f4
  1. 26
      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.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) @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 private final boolean mPictureCaptureStopsPreview = false; // can be configurable at some point
// Actions // Actions
private final List<Action> mActions = new ArrayList<>(); // Use COW to properly synchronize the list. We'll iterate much more than mutate
private final List<Action> mActions = new CopyOnWriteArrayList<>();
private MeterAction mMeterAction; private MeterAction mMeterAction;
public Camera2Engine(Callback callback) { public Camera2Engine(Callback callback) {
@ -1428,28 +1430,14 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
@Override @Override
public void addAction(final @NonNull Action action) { public void addAction(final @NonNull Action action) {
// This is likely to be called during a Capture callback while we iterate if (!mActions.contains(action)) {
// on the actions list, or worse, from other threads. We must use mHandler.post. mActions.add(action);
mHandler.post(new Runnable() { }
@Override
public void run() {
if (!mActions.contains(action)) {
mActions.add(action);
}
}
});
} }
@Override @Override
public void removeAction(final @NonNull Action action) { public void removeAction(final @NonNull Action action) {
// This is likely to be called during a Capture callback while we iterate mActions.remove(action);
// 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);
}
});
} }
@NonNull @NonNull

Loading…
Cancel
Save