/**
* =====================================================================
*
* @file ImageProvider.java
* @Module Name com.nj.common.utils.cache
* @author benz
* @OS version 1.0
* @Product type: JoySee
* @date 2013-12-4
* @brief This file is the http **** implementation.
* @This file is responsible by ANDROID TEAM.
* @Comments: ===================================================================== Revision
* History:
*
* Modification Tracking
*
* Author Date OS version Reason ---------- ------------ ------------- ----------- benz
* 2013-12-4 1.0 Check for NULL, 0 h/w
* =====================================================================
**/
//
package com.letv.commonjar.http;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
import com.letv.commonjar.CLog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.widget.ImageView;
class ImageProvider {
private static final String TAG = CLog.makeTag(ImageProvider.class);
private static final int MSG_CLEAR = 0;
private static final int MSG_FLUSH = 1;
private static final int MSG_CLOSE = 2;
private static final int MSG_INIT_DISK = 3;
private Resources mResources;
private boolean mExitWork = false;
private boolean mPauseWork = false;
private final Object mPauseWorkLock = new Object();
private static ImageProvider mProviderInstance;
private static ImageCache mImageCache;
private final Map<String, WeakReference<Future<?>>> mProcessTaskMap;
private ImageProvider(Context ctx, CacheParams params) {
params = params == null ? new CacheParams(ctx) : params;
mImageCache = new ImageCache(ctx, params);
mResources = ctx.getResources();
mProcessTaskMap = new HashMap<String, WeakReference<Future<?>>>();
new CacheAsyncTask().execute(MSG_INIT_DISK);
}
public static ImageProvider getInstance(Context ctx, CacheParams params) {
if (mProviderInstance == null) {
synchronized (ImageProvider.class) {
if (mProviderInstance == null) {
mProviderInstance = new ImageProvider(ctx, params);
}
}
}
return mProviderInstance;
}
public void flush() {
new CacheAsyncTask().execute(MSG_FLUSH);
}
public void close() {
new CacheAsyncTask().execute(MSG_CLOSE);
}
public void getBitmap(String key, FetchBackListener fb) {
if (key == null || mImageCache == null || fb == null) {
return;
}
BitmapDrawable memoryDrawable = mImageCache.getBitmapFromMemCache(key);
if (memoryDrawable != null) {
fb.fetchSuccess(key, memoryDrawable);
return;
}
BitmapWorkerTask workerTask = new BitmapWorkerTask(key, fb);
workerTask.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR, key);
Future<?> future = workerTask.getFuture();
if (future != null) {
mProcessTaskMap.put(key, new WeakReference<Future<?>>(future));
}
}
public void getBitmap(String key, int[] size, FetchBackListener fb) {
if (key == null || mImageCache == null || fb == null) {
return;
}
BitmapDrawable memoryDrawable = mImageCache.getBitmapFromMemCache(key);
if (memoryDrawable != null) {
if (size != null) {
if (memoryDrawable.getBitmap().getWidth() == size[0] && memoryDrawable.getBitmap().getHeight() == size[1]) {
fb.fetchSuccess(key, memoryDrawable);
return;
}
}
}
BitmapWorkerTask workerTask = new BitmapWorkerTask(key, size, fb);
workerTask.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR, key);
Future<?> future = workerTask.getFuture();
if (future != null) {
mProcessTaskMap.put(key, new WeakReference<Future<?>>(future));
}
}
public void loadImage(String key, ImageView imageView) {
}
public void cancelTask(String url, boolean mayInterruptIfRunning) {
synchronized (mProcessTaskMap) {
WeakReference<Future<?>> futureWR = mProcessTaskMap.get(url);
if (futureWR != null) {
Future<?> request = futureWR.get();
if (request != null) {
request.cancel(mayInterruptIfRunning);
}
mProcessTaskMap.remove(url);
}
}
}
public void cancelTask(ArrayList<String> urls, boolean mayInterruptIfRunning) {
if (urls == null) {
return;
}
synchronized (mProcessTaskMap) {
int size = urls.size();
long begin = CLog.methodBegin(TAG);
for (int i = 0; i < size; i++) {
String url = urls.get(i);
WeakReference<Future<?>> futureWR = mProcessTaskMap.get(url);
if (futureWR != null) {
Future<?> request = futureWR.get();
if (request != null) {
request.cancel(mayInterruptIfRunning);
}
mProcessTaskMap.remove(url);
}
}
CLog.methodEnd(TAG, begin, size + " count");
}
}
public void pauseWork() {
mPauseWork = true;
}
public void continueWork() {
mPauseWork = false;
}
public void exitCacheCient() {
mExitWork = true;
new CacheAsyncTask().execute(MSG_CLOSE);
}
private class BitmapWorkerTask extends AsyncTask<Object, Void, BitmapDrawable> {
private String key;
private int[] size;
private FetchBackListener fb;
public BitmapWorkerTask(String key, FetchBackListener fb) {
this.key = key;
this.fb = fb;
}
public BitmapWorkerTask(String key, int[] size, FetchBackListener fb) {
this.key = key;
this.fb = fb;
this.size = size;
}
@Override
protected BitmapDrawable doInBackground(Object... params) {
key = String.valueOf(params[0]);
Bitmap bitmap = null;
BitmapDrawable drawable = null;
synchronized (mPauseWorkLock) {
while (mPauseWork && !isCancelled()) {
try {
mPauseWorkLock.wait();
} catch (InterruptedException e) {}
}
}
/**
* get from disk
*/
if (mImageCache != null && !mExitWork) {
bitmap = mImageCache.getBitmapFromDiskCache(key, size);
}
/**
* get from net
*/
if (bitmap == null && !isCancelled() && !mExitWork) {
bitmap = mImageCache.processBitmap(key, size);
}
/**
* add to cache
*/
if (bitmap != null) {
drawable = new BitmapDrawable(mResources, bitmap);
if (mImageCache != null) {
mImageCache.addBitmapToCache(key, drawable);
}
}
return drawable;
}
@Override
protected void onPostExecute(BitmapDrawable value) {
if (isCancelled() || mExitWork) {
value = null;
}
if (fb != null) {
fb.fetchSuccess(key, value);
}
}
@Override
protected void onCancelled(BitmapDrawable value) {
super.onCancelled(value);
synchronized (mPauseWorkLock) {
mPauseWorkLock.notifyAll();
}
}
}
protected class CacheAsyncTask extends AsyncTask<Object, Void, Void> {
@Override
protected Void doInBackground(Object... params) {
if (mImageCache != null) {
switch ((Integer) params[0]) {
case MSG_CLEAR:
mImageCache.clearCache();
break;
case MSG_FLUSH:
mImageCache.flush();
break;
case MSG_CLOSE:
mImageCache.close();
break;
case MSG_INIT_DISK:
mImageCache.initDiskCache();
break;
}
}
return null;
}
}
}