diff options
author | David Morrissey <davemorrissey@gmail.com> | 2017-11-23 14:17:47 +0000 |
---|---|---|
committer | David Morrissey <davemorrissey@gmail.com> | 2017-11-23 14:17:47 +0000 |
commit | 33f748109bf36bc5fad78bb110e63be2c8e687ed (patch) | |
tree | 7b19acd3e1ff65a009267fa101be645ec7a40338 /library/src/main/java/com/davemorrissey/labs | |
parent | 042bc8f4323e31ab9b477be0917ae6415fb0ecf6 (diff) | |
download | subsampling-scale-image-view-33f748109bf36bc5fad78bb110e63be2c8e687ed.tar.gz |
Allow a custom and dedicated executor to be used for tile loading
Diffstat (limited to 'library/src/main/java/com/davemorrissey/labs')
-rw-r--r-- | library/src/main/java/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java | 41 |
1 files changed, 27 insertions, 14 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 a9718b3..b28d8a7 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,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.concurrent.Executor; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -173,8 +174,8 @@ public class SubsamplingScaleImageView extends View { private int maxTileWidth = TILE_SIZE_AUTO; private int maxTileHeight = TILE_SIZE_AUTO; - // Whether to use the thread pool executor to load tiles - private boolean parallelLoadingEnabled; + // An executor service for loading of images + private Executor executor = AsyncTask.SERIAL_EXECUTOR; // Gesture detection settings private boolean panEnabled = true; @@ -1846,11 +1847,7 @@ public class SubsamplingScaleImageView extends View { } private void execute(AsyncTask<Void, Void, ?> asyncTask) { - if (parallelLoadingEnabled) { - asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else { - asyncTask.execute(); - } + asyncTask.executeOnExecutor(executor); } private static class Tile { @@ -2750,13 +2747,29 @@ public class SubsamplingScaleImageView extends View { } /** - * Toggle parallel loading. When enabled, tiles are loaded using the thread pool executor. - * Parallel loading may use more memory and there is a possibility that it will make the tile - * loading unreliable, but it reduces the chances of an app's background processes blocking loading. - * @param parallelLoadingEnabled Whether to run AsyncTasks using a thread pool executor. - */ - public void setParallelLoadingEnabled(boolean parallelLoadingEnabled) { - this.parallelLoadingEnabled = parallelLoadingEnabled; + * <p> + * Provide an {@link Executor} to be used for loading images. By default, {@link AsyncTask#SERIAL_EXECUTOR} + * is used, and this can cause slow loading when this executor is being used for other tasks e.g. + * loading data from the network. You can use {@link AsyncTask#THREAD_POOL_EXECUTOR} to reduce + * the likelihood of contention, or supply an {@link Executor} of your own to avoid any contention. + * It is strongly recommended to use a single executor instance for the life of your application, + * not one per view instance. + * </p><p> + * <b>Warning:</b> If you are using a custom implementation of {@link ImageRegionDecoder}, and you + * supply an executor with more than one thread, you must make sure your implementation supports + * multi-threaded bitmap decoding or has appropriate internal synchronization. Android's + * {@link android.graphics.BitmapRegionDecoder} uses an internal lock so it is thread safe but + * there is no advantage to using multiple threads. + * </p><p> + * <b>Note:</b> Using an executor with multiple threads may increase memory usage. + * </p> + * @param executor an {@link Executor} for image loading. + */ + public void setExecutor(Executor executor) { + if (executor == null) { + throw new NullPointerException("Executor must not be null"); + } + this.executor = executor; } /** |