Better fix for concurrency issue

git-svn-id: https://zxing.googlecode.com/svn/trunk@1794 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2011-05-21 03:36:08 +00:00
parent c8166aec33
commit 87887ab18c

View file

@ -30,7 +30,6 @@ import android.view.View;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/** /**
* This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial * This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial
@ -53,8 +52,8 @@ public final class ViewfinderView extends View {
private final int laserColor; private final int laserColor;
private final int resultPointColor; private final int resultPointColor;
private int scannerAlpha; private int scannerAlpha;
private final AtomicReference<List<ResultPoint>> possibleResultPoints; private List<ResultPoint> possibleResultPoints;
private final AtomicReference<List<ResultPoint>> lastPossibleResultPoints; private List<ResultPoint> lastPossibleResultPoints;
// This constructor is used when the class is built from an XML resource. // This constructor is used when the class is built from an XML resource.
public ViewfinderView(Context context, AttributeSet attrs) { public ViewfinderView(Context context, AttributeSet attrs) {
@ -69,9 +68,8 @@ public final class ViewfinderView extends View {
laserColor = resources.getColor(R.color.viewfinder_laser); laserColor = resources.getColor(R.color.viewfinder_laser);
resultPointColor = resources.getColor(R.color.possible_result_points); resultPointColor = resources.getColor(R.color.possible_result_points);
scannerAlpha = 0; scannerAlpha = 0;
possibleResultPoints = new AtomicReference<List<ResultPoint>>(); possibleResultPoints = new ArrayList<ResultPoint>(5);
lastPossibleResultPoints = new AtomicReference<List<ResultPoint>>(); lastPossibleResultPoints = null;
possibleResultPoints.set(new ArrayList<ResultPoint>(5));
} }
@Override @Override
@ -114,28 +112,32 @@ public final class ViewfinderView extends View {
float scaleX = frame.width() / (float) previewFrame.width(); float scaleX = frame.width() / (float) previewFrame.width();
float scaleY = frame.height() / (float) previewFrame.height(); float scaleY = frame.height() / (float) previewFrame.height();
List<ResultPoint> currentPossible = possibleResultPoints.get(); List<ResultPoint> currentPossible = possibleResultPoints;
List<ResultPoint> currentLast = lastPossibleResultPoints.get(); List<ResultPoint> currentLast = lastPossibleResultPoints;
if (currentPossible.isEmpty()) { if (currentPossible.isEmpty()) {
lastPossibleResultPoints.set(null); lastPossibleResultPoints = null;
} else { } else {
possibleResultPoints.set(new ArrayList<ResultPoint>(5)); possibleResultPoints = new ArrayList<ResultPoint>(5);
lastPossibleResultPoints.set(currentPossible); lastPossibleResultPoints = currentPossible;
paint.setAlpha(CURRENT_POINT_OPACITY); paint.setAlpha(CURRENT_POINT_OPACITY);
paint.setColor(resultPointColor); paint.setColor(resultPointColor);
for (ResultPoint point : currentPossible) { synchronized (currentPossible) {
canvas.drawCircle(frame.left + (int) (point.getX() * scaleX), for (ResultPoint point : currentPossible) {
frame.top + (int) (point.getY() * scaleY), canvas.drawCircle(frame.left + (int) (point.getX() * scaleX),
6.0f, paint); frame.top + (int) (point.getY() * scaleY),
6.0f, paint);
}
} }
} }
if (currentLast != null) { if (currentLast != null) {
paint.setAlpha(CURRENT_POINT_OPACITY / 2); paint.setAlpha(CURRENT_POINT_OPACITY / 2);
paint.setColor(resultPointColor); paint.setColor(resultPointColor);
for (ResultPoint point : currentLast) { synchronized (currentLast) {
canvas.drawCircle(frame.left + (int) (point.getX() * scaleX), for (ResultPoint point : currentLast) {
frame.top + (int) (point.getY() * scaleY), canvas.drawCircle(frame.left + (int) (point.getX() * scaleX),
3.0f, paint); frame.top + (int) (point.getY() * scaleY),
3.0f, paint);
}
} }
} }
@ -161,11 +163,14 @@ public final class ViewfinderView extends View {
} }
public void addPossibleResultPoint(ResultPoint point) { public void addPossibleResultPoint(ResultPoint point) {
List<ResultPoint> points = possibleResultPoints.get(); List<ResultPoint> points = possibleResultPoints;
points.add(point); synchronized (point) {
if (points.size() > MAX_RESULT_POINTS) { points.add(point);
// trim it int size = points.size();
points.subList(0, points.size() - MAX_RESULT_POINTS / 2).clear(); if (size > MAX_RESULT_POINTS) {
// trim it
points.subList(0, size - MAX_RESULT_POINTS / 2).clear();
}
} }
} }