I have two following methods those load my Bitmaps
. And when I've tried to load huge image 2000px x 6000px
I've got UI
freeze for about 3 seconds. Can anubody help me to improve loading speed of huge images? I's important for me on screen orientation change, because these methods always have been called by that lib and my UI always freezes for about 3 second before rotate...
/**
* Async task used to get image details
*/
private static class TilesInitTask implements Runnable {
private final WeakReference<ScaleImageView> viewRef;
private final WeakReference<Context> contextRef;
private final WeakReference<DecoderFactory<? extends ImageRegionDecoder>> decoderFactoryRef;
private final Uri source;
private ImageRegionDecoder decoder;
private Exception exception;
public TilesInitTask(ScaleImageView view, Context context, DecoderFactory<? extends ImageRegionDecoder> decoderFactory, Uri source) {
this.viewRef = new WeakReference<>(view);
this.contextRef = new WeakReference<>(context);
this.decoderFactoryRef = new WeakReference<DecoderFactory<? extends ImageRegionDecoder>>(decoderFactory);
this.source = source;
}
public void run() {
ScaleImageView view = null;
try {
String sourceUri = source.toString();
Context context = contextRef.get();
DecoderFactory<? extends ImageRegionDecoder> decoderFactory = decoderFactoryRef.get();
view = viewRef.get();
if (context != null && decoderFactory != null && view != null) {
decoder = decoderFactory.make();
Point dimensions = decoder.init(context, source);
int sWidth = dimensions.x;
int sHeight = dimensions.y;
int exifOrientation = view.getExifOrientation(sourceUri);
if (view.sRegion != null) {
sWidth = view.sRegion.width();
sHeight = view.sRegion.height();
}
view.onTilesInited(decoder, sWidth, sHeight, exifOrientation);
}
} catch (Exception e) {
Log.e(TAG, "Failed to initialise bitmap decoder", e);
this.exception = e;
if (view != null && view.onImageEventListener != null) {
view.onImageEventListener.onImageLoadError(exception);
}
}
}
}
/**
* Called by worker task when decoder is ready and image size and EXIF orientation is known.
*/
private synchronized void onTilesInited(ImageRegionDecoder decoder, int sWidth, int sHeight, int sOrientation) {
// If actual dimensions don't match the declared size, reset everything.
if (this.sWidth > 0 && this.sHeight > 0 && (this.sWidth != sWidth || this.sHeight != sHeight)) {
reset(false);
if (bitmap != null) {
if (!bitmapIsCached) {
bitmap.recycle();
}
bitmap = null;
bitmapIsPreview = false;
bitmapIsCached = false;
}
}
this.decoder = decoder;
this.sWidth = sWidth;
this.sHeight = sHeight;
this.sOrientation = sOrientation;
checkReady();
checkImageLoaded();
invalidate();
requestLayout();
}
/**
* Async task used to load images
*/
private static class TileLoadTask implements Runnable {
private final WeakReference<ScaleImageView> viewRef;
private final WeakReference<ImageRegionDecoder> decoderRef;
private final WeakReference<Tile> tileRef;
private Exception exception;
public TileLoadTask(ScaleImageView view, ImageRegionDecoder decoder, Tile tile) {
this.viewRef = new WeakReference<>(view);
this.decoderRef = new WeakReference<>(decoder);
this.tileRef = new WeakReference<>(tile);
tile.loading = true;
}
public void run() {
ScaleImageView view = null;
try {
view = viewRef.get();
ImageRegionDecoder decoder = decoderRef.get();
Tile tile = tileRef.get();
if (decoder != null && tile != null && view != null && decoder.isReady()) {
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);
}
tile.bitmap = decoder.decodeRegion(tile.fileSRect, tile.sampleSize);
tile.loading = false;
view.onTileLoaded();
}
} else if (tile != null) {
tile.loading = false;
}
} catch (Exception e) {
Log.e(TAG, "Failed to decode tile", e);
this.exception = e;
if (view != null && view.onImageEventListener != null) {
view.onImageEventListener.onTileLoadError(exception);
}
}
}
}
/**
* Called by worker task when a tile has loaded. Redraws the view.
*/
private synchronized void onTileLoaded() {
checkReady();
checkImageLoaded();
if (isBaseLayerReady() && bitmap != null) {
if (!bitmapIsCached) {
bitmap.recycle();
}
bitmap = null;
bitmapIsPreview = false;
bitmapIsCached = false;
}
invalidate();
}