public class SkiaPooledImageRegionDecoder extends Object implements ImageRegionDecoder
An implementation of ImageRegionDecoder
using a pool of BitmapRegionDecoder
s,
to provide true parallel loading of tiles. This is only effective if parallel loading has been
enabled in the view by calling SubsamplingScaleImageView.setExecutor(Executor)
with a multi-threaded Executor
instance.
One decoder is initialised when the class is initialised. This is enough to decode base layer tiles.
Additional decoders are initialised when a subregion of the image is first requested, which indicates
interaction with the view. Creation of additional encoders stops when allowAdditionalDecoder(int, long)
returns false. The default implementation takes into account the file size, number of CPU cores,
low memory status and a hard limit of 4. Extend this class to customise this.
WARNING: This class is highly experimental and not proven to be stable on a wide range of
devices. You are advised to test it thoroughly on all available devices, and code your app to use
SkiaImageRegionDecoder
on old or low powered devices you could not test.
Constructor and Description |
---|
SkiaPooledImageRegionDecoder() |
SkiaPooledImageRegionDecoder(Bitmap.Config bitmapConfig) |
Modifier and Type | Method and Description |
---|---|
protected boolean |
allowAdditionalDecoder(int numberOfDecoders,
long fileLength)
Called before creating a new decoder.
|
Bitmap |
decodeRegion(Rect sRect,
int sampleSize)
Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
exists and acquire a decoder to load the requested region.
|
Point |
init(Context context,
Uri uri)
Initialises the decoder pool.
|
boolean |
isReady()
Holding a read lock to avoid returning true while the pool is being recycled, this returns
true if the pool has at least one decoder available.
|
void |
recycle()
Wait until all read locks held by
decodeRegion(Rect, int) are released, then recycle
and destroy the pool. |
static void |
setDebug(boolean debug)
Controls logging of debug messages.
|
public SkiaPooledImageRegionDecoder()
public SkiaPooledImageRegionDecoder(Bitmap.Config bitmapConfig)
public static void setDebug(boolean debug)
debug
- true to enable debug logging, false to disable.public Point init(Context context, Uri uri) throws Exception
recycle()
is called.init
in interface ImageRegionDecoder
context
- Application context. A reference may be held, but must be cleared on recycle.uri
- URI of the image.Exception
- if initialisation fails.public Bitmap decodeRegion(Rect sRect, int sampleSize)
init(Context, Uri)
is called and be null once recycle()
is called. In practice the view can't call this
method until after init(Context, Uri)
, so there will be no blocking on an empty pool.decodeRegion
in interface ImageRegionDecoder
sRect
- Source image rectangle to decode.sampleSize
- Sample size.public boolean isReady()
isReady
in interface ImageRegionDecoder
public void recycle()
decodeRegion(Rect, int)
are released, then recycle
and destroy the pool. Elsewhere, when a read lock is acquired, we must check the pool is not null.recycle
in interface ImageRegionDecoder
protected boolean allowAdditionalDecoder(int numberOfDecoders, long fileLength)
numberOfDecoders
- the number of decoders that have been created so farfileLength
- the size of the image file in bytes. Creating another decoder will use approximately this much native memory.