ImageLoader.java
/*
* Decompiled with CFR 0_132.
*
* Could not load the following classes:
* android.annotation.SuppressLint
* android.app.ActivityManager
* android.content.Context
* android.graphics.Bitmap
* android.graphics.Paint
* android.graphics.drawable.BitmapDrawable
* android.graphics.drawable.Drawable
* android.text.TextUtils
* android.view.animation.Animation
* android.widget.ImageView
* android.widget.ImageView$ScaleType
*/
package org.xutils.image;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.animation.Animation;
import android.widget.ImageView;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicLong;
import org.xutils.cache.LruCache;
import org.xutils.cache.LruDiskCache;
import org.xutils.common.Callback;
import org.xutils.common.task.Priority;
import org.xutils.common.task.PriorityExecutor;
import org.xutils.common.util.IOUtil;
import org.xutils.common.util.LogUtil;
import org.xutils.ex.FileLockedException;
import org.xutils.http.RequestParams;
import org.xutils.image.AsyncDrawable;
import org.xutils.image.GifDrawable;
import org.xutils.image.ImageAnimationHelper;
import org.xutils.image.ImageDecoder;
import org.xutils.image.ImageOptions;
import org.xutils.image.MemCacheKey;
import org.xutils.image.ReusableDrawable;
import org.xutils.x;
final class ImageLoader
implements Callback.PrepareCallback<File, Drawable>,
Callback.CacheCallback<Drawable>,
Callback.ProgressCallback<Drawable>,
Callback.TypedCallback<Drawable>,
Callback.Cancelable {
private MemCacheKey key;
private ImageOptions options;
private WeakReference<ImageView> viewRef;
private static final AtomicLong SEQ_SEEK = new AtomicLong(0L);
private final long seq = SEQ_SEEK.incrementAndGet();
private volatile boolean stopped = false;
private volatile boolean cancelled = false;
private Callback.Cancelable cancelable;
private Callback.CommonCallback<Drawable> callback;
private Callback.PrepareCallback<File, Drawable> prepareCallback;
private Callback.CacheCallback<Drawable> cacheCallback;
private Callback.ProgressCallback<Drawable> progressCallback;
private static final String DISK_CACHE_DIR_NAME = "xUtils_img";
private static final Executor EXECUTOR = new PriorityExecutor(10, false);
private static final int MEM_CACHE_MIN_SIZE = 4194304;
private static final LruCache<MemCacheKey, Drawable> MEM_CACHE = new LruCache<MemCacheKey, Drawable>(4194304){
private boolean deepClear = false;
@Override
protected int sizeOf(MemCacheKey key, Drawable value) {
if (value instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable)value).getBitmap();
return bitmap == null ? 0 : bitmap.getByteCount();
}
if (value instanceof GifDrawable) {
return ((GifDrawable)value).getByteCount();
}
return super.sizeOf(key, value);
}
@Override
public void trimToSize(int maxSize) {
if (maxSize < 0) {
this.deepClear = true;
}
super.trimToSize(maxSize);
this.deepClear = false;
}
@Override
protected void entryRemoved(boolean evicted, MemCacheKey key, Drawable oldValue, Drawable newValue) {
super.entryRemoved(evicted, key, oldValue, newValue);
if (evicted && this.deepClear && oldValue instanceof ReusableDrawable) {
((ReusableDrawable)oldValue).setMemCacheKey(null);
}
}
};
private static final HashMap<String, FakeImageView> FAKE_IMG_MAP;
private static final Type loadType;
private boolean hasCache = false;
private ImageLoader() {
}
static void clearMemCache() {
MEM_CACHE.evictAll();
}
static void clearCacheFiles() {
LruDiskCache.getDiskCache(DISK_CACHE_DIR_NAME).clearCacheFiles();
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
static Callback.Cancelable doLoadDrawable(String url, ImageOptions options, Callback.CommonCallback<Drawable> callback) {
if (TextUtils.isEmpty((CharSequence)url)) {
ImageLoader.postArgsException(null, options, "url is null", callback);
return null;
}
FakeImageView fakeImageView = null;
HashMap<String, FakeImageView> hashMap = FAKE_IMG_MAP;
synchronized (hashMap) {
fakeImageView = FAKE_IMG_MAP.get(url);
if (fakeImageView == null) {
fakeImageView = new FakeImageView();
}
}
return ImageLoader.doBind(fakeImageView, url, options, callback);
}
static Callback.Cancelable doLoadFile(String url, ImageOptions options, Callback.CacheCallback<File> callback) {
if (TextUtils.isEmpty((CharSequence)url)) {
ImageLoader.postArgsException(null, options, "url is null", callback);
return null;
}
RequestParams params = ImageLoader.createRequestParams(url, options);
return x.http().get(params, callback);
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled force condition propagation
* Lifted jumps to return sites
*/
static Callback.Cancelable doBind(ImageView view, String url, ImageOptions options, Callback.CommonCallback<Drawable> callback) {
Bitmap bitmap;
MemCacheKey oldKey;
ImageOptions localOptions = options;
if (view == null) {
ImageLoader.postArgsException(null, localOptions, "view is null", callback);
return null;
}
if (TextUtils.isEmpty((CharSequence)url)) {
ImageLoader.postArgsException(view, localOptions, "url is null", callback);
return null;
}
if (localOptions == null) {
localOptions = ImageOptions.DEFAULT;
}
localOptions.optimizeMaxSize(view);
MemCacheKey key = new MemCacheKey(url, localOptions);
Drawable oldDrawable = view.getDrawable();
if (oldDrawable instanceof AsyncDrawable) {
ImageLoader loader = ((AsyncDrawable)oldDrawable).getImageLoader();
if (loader != null && !loader.stopped) {
if (key.equals(loader.key)) {
return null;
}
loader.cancel();
}
} else if (oldDrawable instanceof ReusableDrawable && (oldKey = ((ReusableDrawable)oldDrawable).getMemCacheKey()) != null && oldKey.equals(key)) {
MEM_CACHE.put(key, oldDrawable);
}
Drawable memDrawable = null;
if (!localOptions.isUseMemCache()) return new ImageLoader().doLoad(view, url, localOptions, callback);
memDrawable = MEM_CACHE.get(key);
if (memDrawable instanceof BitmapDrawable && ((bitmap = ((BitmapDrawable)memDrawable).getBitmap()) == null || bitmap.isRecycled())) {
return new ImageLoader().doLoad(view, url, localOptions, callback);
}
if (memDrawable == null) return new ImageLoader().doLoad(view, url, localOptions, callback);
boolean trustMemCache = false;
try {
if (callback instanceof Callback.ProgressCallback) {
((Callback.ProgressCallback)callback).onWaiting();
}
view.setScaleType(localOptions.getImageScaleType());
view.setImageDrawable(memDrawable);
trustMemCache = true;
if (callback instanceof Callback.CacheCallback) {
trustMemCache = ((Callback.CacheCallback)callback).onCache(memDrawable);
if (trustMemCache) return null;
Callback.Cancelable cancelable = new ImageLoader().doLoad(view, url, localOptions, callback);
return cancelable;
}
if (callback == null) return null;
callback.onSuccess(memDrawable);
return null;
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
trustMemCache = false;
Callback.Cancelable ignored = new ImageLoader().doLoad(view, url, localOptions, callback);
return ignored;
}
finally {
if (trustMemCache && callback != null) {
try {
callback.onFinished();
}
catch (Throwable ignored) {
LogUtil.e(ignored.getMessage(), ignored);
}
}
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
private Callback.Cancelable doLoad(ImageView view, String url, ImageOptions options, Callback.CommonCallback<Drawable> callback) {
this.viewRef = new WeakReference<ImageView>(view);
this.options = options;
this.key = new MemCacheKey(url, options);
this.callback = callback;
if (callback instanceof Callback.ProgressCallback) {
this.progressCallback = (Callback.ProgressCallback)callback;
}
if (callback instanceof Callback.PrepareCallback) {
this.prepareCallback = (Callback.PrepareCallback)callback;
}
if (callback instanceof Callback.CacheCallback) {
this.cacheCallback = (Callback.CacheCallback)callback;
}
Drawable loadingDrawable = null;
if (options.isForceLoadingDrawable()) {
loadingDrawable = options.getLoadingDrawable(view);
view.setScaleType(options.getPlaceholderScaleType());
view.setImageDrawable((Drawable)new AsyncDrawable(this, loadingDrawable));
} else {
loadingDrawable = view.getDrawable();
view.setImageDrawable((Drawable)new AsyncDrawable(this, loadingDrawable));
}
RequestParams params = ImageLoader.createRequestParams(url, options);
if (view instanceof FakeImageView) {
HashMap<String, FakeImageView> hashMap = FAKE_IMG_MAP;
synchronized (hashMap) {
FAKE_IMG_MAP.put(url, (FakeImageView)view);
}
}
this.cancelable = x.http().get(params, this);
return this.cancelable;
}
@Override
public void cancel() {
this.stopped = true;
this.cancelled = true;
if (this.cancelable != null) {
this.cancelable.cancel();
}
}
@Override
public boolean isCancelled() {
return this.cancelled || !this.validView4Callback(false);
}
@Override
public void onWaiting() {
if (this.progressCallback != null) {
this.progressCallback.onWaiting();
}
}
@Override
public void onStarted() {
if (this.validView4Callback(true) && this.progressCallback != null) {
this.progressCallback.onStarted();
}
}
@Override
public void onLoading(long total, long current, boolean isDownloading) {
if (this.validView4Callback(true) && this.progressCallback != null) {
this.progressCallback.onLoading(total, current, isDownloading);
}
}
@Override
public Type getLoadType() {
return loadType;
}
@Override
public Drawable prepare(File rawData) {
if (!this.validView4Callback(true)) {
return null;
}
try {
Drawable result = null;
if (this.prepareCallback != null) {
result = this.prepareCallback.prepare(rawData);
}
if (result == null) {
result = ImageDecoder.decodeFileWithLock(rawData, this.options, this);
}
if (result != null && result instanceof ReusableDrawable) {
((ReusableDrawable)result).setMemCacheKey(this.key);
MEM_CACHE.put(this.key, result);
}
return result;
}
catch (IOException ex) {
IOUtil.deleteFileOrDir(rawData);
LogUtil.w(ex.getMessage(), ex);
return null;
}
}
@Override
public boolean onCache(Drawable result) {
if (!this.validView4Callback(true)) {
return false;
}
if (result != null) {
this.hasCache = true;
this.setSuccessDrawable4Callback(result);
if (this.cacheCallback != null) {
return this.cacheCallback.onCache(result);
}
if (this.callback != null) {
this.callback.onSuccess(result);
return true;
}
return true;
}
return false;
}
@Override
public void onSuccess(Drawable result) {
if (!this.validView4Callback(!this.hasCache)) {
return;
}
if (result != null) {
this.setSuccessDrawable4Callback(result);
if (this.callback != null) {
this.callback.onSuccess(result);
}
}
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
this.stopped = true;
if (!this.validView4Callback(false)) {
return;
}
if (ex instanceof FileLockedException) {
LogUtil.d("ImageFileLocked: " + this.key.url);
x.task().postDelayed(new Runnable(){
@Override
public void run() {
ImageLoader.doBind((ImageView)ImageLoader.this.viewRef.get(), ImageLoader.access$100((ImageLoader)ImageLoader.this).url, ImageLoader.this.options, ImageLoader.this.callback);
}
}, 10L);
return;
}
LogUtil.e(this.key.url, ex);
this.setErrorDrawable4Callback();
if (this.callback != null) {
this.callback.onError(ex, isOnCallback);
}
}
@Override
public void onCancelled(Callback.CancelledException cex) {
this.stopped = true;
if (!this.validView4Callback(false)) {
return;
}
if (this.callback != null) {
this.callback.onCancelled(cex);
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
@Override
public void onFinished() {
this.stopped = true;
ImageView view = this.viewRef.get();
if (view instanceof FakeImageView) {
HashMap<String, FakeImageView> hashMap = FAKE_IMG_MAP;
synchronized (hashMap) {
FAKE_IMG_MAP.remove(this.key.url);
}
}
if (!this.validView4Callback(false)) {
return;
}
if (this.callback != null) {
this.callback.onFinished();
}
}
private static RequestParams createRequestParams(String url, ImageOptions options) {
ImageOptions.ParamsBuilder paramsBuilder;
RequestParams params = new RequestParams(url);
params.setCacheDirName(DISK_CACHE_DIR_NAME);
params.setConnectTimeout(8000);
params.setPriority(Priority.BG_LOW);
params.setExecutor(EXECUTOR);
params.setCancelFast(true);
params.setUseCookie(false);
if (options != null && (paramsBuilder = options.getParamsBuilder()) != null) {
params = paramsBuilder.buildParams(params, options);
}
return params;
}
private boolean validView4Callback(boolean forceValidAsyncDrawable) {
ImageView view = this.viewRef.get();
if (view != null) {
Drawable otherDrawable = view.getDrawable();
if (otherDrawable instanceof AsyncDrawable) {
ImageLoader otherLoader = ((AsyncDrawable)otherDrawable).getImageLoader();
if (otherLoader != null) {
if (otherLoader == this) {
if (view.getVisibility() != 0) {
otherLoader.cancel();
return false;
}
return true;
}
if (this.seq > otherLoader.seq) {
otherLoader.cancel();
return true;
}
this.cancel();
return false;
}
} else if (forceValidAsyncDrawable) {
this.cancel();
return false;
}
return true;
}
return false;
}
private void setSuccessDrawable4Callback(Drawable drawable) {
ImageView view = this.viewRef.get();
if (view != null) {
view.setScaleType(this.options.getImageScaleType());
if (drawable instanceof GifDrawable) {
if (view.getScaleType() == ImageView.ScaleType.CENTER) {
view.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
}
view.setLayerType(1, null);
}
if (this.options.getAnimation() != null) {
ImageAnimationHelper.animationDisplay(view, drawable, this.options.getAnimation());
} else if (this.options.isFadeIn()) {
ImageAnimationHelper.fadeInDisplay(view, drawable);
} else {
view.setImageDrawable(drawable);
}
}
}
private void setErrorDrawable4Callback() {
ImageView view = this.viewRef.get();
if (view != null) {
Drawable drawable = this.options.getFailureDrawable(view);
view.setScaleType(this.options.getPlaceholderScaleType());
view.setImageDrawable(drawable);
}
}
private static void postArgsException(final ImageView view, final ImageOptions options, final String exMsg, final Callback.CommonCallback<?> callback) {
x.task().autoPost(new Runnable(){
@Override
public void run() {
try {
if (callback instanceof Callback.ProgressCallback) {
((Callback.ProgressCallback)callback).onWaiting();
}
if (view != null && options != null) {
view.setScaleType(options.getPlaceholderScaleType());
view.setImageDrawable(options.getFailureDrawable(view));
}
if (callback != null) {
callback.onError(new IllegalArgumentException(exMsg), false);
}
}
catch (Throwable ex) {
if (callback != null) {
try {
callback.onError(ex, true);
}
catch (Throwable ignored) {
LogUtil.e(ignored.getMessage(), ignored);
}
}
}
finally {
if (callback != null) {
try {
callback.onFinished();
}
catch (Throwable ignored) {
LogUtil.e(ignored.getMessage(), ignored);
}
}
}
}
});
}
static /* synthetic */ MemCacheKey access$100(ImageLoader x0) {
return x0.key;
}
static {
int memClass = ((ActivityManager)x.app().getSystemService("activity")).getMemoryClass();
int cacheSize = 1048576 * memClass / 8;
if (cacheSize < 4194304) {
cacheSize = 4194304;
}
MEM_CACHE.resize(cacheSize);
FAKE_IMG_MAP = new HashMap();
loadType = File.class;
}
@SuppressLint(value={"ViewConstructor"})
private static final class FakeImageView
extends ImageView {
private Drawable drawable;
public FakeImageView() {
super((Context)x.app());
}
public void setImageDrawable(Drawable drawable) {
this.drawable = drawable;
}
public Drawable getDrawable() {
return this.drawable;
}
public void setLayerType(int layerType, Paint paint) {
}
public void setScaleType(ImageView.ScaleType scaleType) {
}
public void startAnimation(Animation animation) {
}
}
}