aboutsummaryrefslogtreecommitdiff
path: root/library/src/main
diff options
context:
space:
mode:
authorDavid Morrissey <davemorrissey@gmail.com>2017-11-23 14:06:56 +0000
committerDavid Morrissey <davemorrissey@gmail.com>2017-11-23 14:06:56 +0000
commit042bc8f4323e31ab9b477be0917ae6415fb0ecf6 (patch)
tree683581d8a8b142df50ea6d18a6f6f1b2e68f757f /library/src/main
parentc947ca46810bb0da96be490ab40897487ba3073b (diff)
downloadsubsampling-scale-image-view-042bc8f4323e31ab9b477be0917ae6415fb0ecf6.tar.gz
Use ReadWriteLock to delegate synchronization to decoder classes while allowing safe recycling
Diffstat (limited to 'library/src/main')
-rw-r--r--library/src/main/java/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java30
1 files changed, 21 insertions, 9 deletions
diff --git a/library/src/main/java/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java b/library/src/main/java/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java
index da170d7..a9718b3 100644
--- a/library/src/main/java/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java
+++ b/library/src/main/java/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java
@@ -46,6 +46,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* <p>
@@ -220,7 +222,7 @@ public class SubsamplingScaleImageView extends View {
// Tile and image decoding
private ImageRegionDecoder decoder;
- private final Object decoderLock = new Object();
+ private final ReadWriteLock decoderLock = new ReentrantReadWriteLock(true);
private DecoderFactory<? extends ImageDecoder> bitmapDecoderFactory = new CompatDecoderFactory<ImageDecoder>(SkiaImageDecoder.class);
private DecoderFactory<? extends ImageRegionDecoder> regionDecoderFactory = new CompatDecoderFactory<ImageRegionDecoder>(SkiaImageRegionDecoder.class);
@@ -474,11 +476,14 @@ public class SubsamplingScaleImageView extends View {
sRect = null;
if (newImage) {
uri = null;
- if (decoder != null) {
- synchronized (decoderLock) {
+ decoderLock.writeLock().lock();
+ try {
+ if (decoder != null) {
decoder.recycle();
decoder = null;
}
+ } finally {
+ decoderLock.writeLock().unlock();
}
if (bitmap != null && !bitmapIsCached) {
bitmap.recycle();
@@ -1609,13 +1614,20 @@ public class SubsamplingScaleImageView extends View {
Tile tile = tileRef.get();
if (decoder != null && tile != null && view != null && decoder.isReady() && tile.visible) {
view.debug("TileLoadTask.doInBackground, tile.sRect=%s, tile.sampleSize=%d", tile.sRect, tile.sampleSize);
- synchronized (view.decoderLock) {
- // Update tile's file sRect according to rotation
- view.fileSRect(tile.sRect, tile.fileSRect);
- if (view.sRegion != null) {
- tile.fileSRect.offset(view.sRegion.left, view.sRegion.top);
+ view.decoderLock.readLock().lock();
+ try {
+ if (decoder.isReady()) {
+ // Update tile's file sRect according to rotation
+ view.fileSRect(tile.sRect, tile.fileSRect);
+ if (view.sRegion != null) {
+ tile.fileSRect.offset(view.sRegion.left, view.sRegion.top);
+ }
+ return decoder.decodeRegion(tile.fileSRect, tile.sampleSize);
+ } else {
+ tile.loading = false;
}
- return decoder.decodeRegion(tile.fileSRect, tile.sampleSize);
+ } finally {
+ view.decoderLock.readLock().unlock();
}
} else if (tile != null) {
tile.loading = false;