/**
* Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.minggo.pluto.bitmap;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.widget.ImageView;
import com.minggo.pluto.Pluto;
import com.minggo.pluto.util.LogUtils;
import com.minggo.pluto.util.PhotoUtil;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class FinalBitmap {
private FinalBitmapConfig mConfig;
private static BitmapCache mImageCache;
private boolean mExitTasksEarly = false;
private boolean mPauseWork = false;
private final Object mPauseWorkLock = new Object();
private Context mContext;
private float memerySize;
private static ExecutorService bitmapLoadAndDisplayExecutor;
private static FinalBitmap mFinalBitmap;
// //////////////////////// config method
// start////////////////////////////////////
private FinalBitmap(Context context) {
mContext = context;
mConfig = new FinalBitmapConfig(context);
configDiskCachePath(BitmapCommonUtils.getDiskCacheDir(context, Pluto.FINAL_BIMAP_SAVE_PATH).getAbsolutePath());// 配置缓存路径
configDisplayer(new SimpleDisplayer());// 配置显示器
configDownlader(new SimpleHttpDownloader());// 配置下载器
}
/**
* 创建finalbitmap
*
* @param ctx
* @return
*/
public static FinalBitmap create(Context ctx) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 创建finalBitmap
*
* @param ctx
* @param diskCachePath
* 磁盘缓存路径
* @return
*/
public static FinalBitmap create(Context ctx, String diskCachePath) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.configDiskCachePath(diskCachePath);
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 创建finalBitmap
*
* @param ctx
* @param diskCachePath
* 磁盘缓存路径
* @param memoryCacheSizePercent
* 缓存大小在当前进程的百分比(0.05-0.8之间)
* @return
*/
public static FinalBitmap create(Context ctx, String diskCachePath, float memoryCacheSizePercent) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.configDiskCachePath(diskCachePath);
mFinalBitmap.configMemoryCachePercent(memoryCacheSizePercent);
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 创建finalBitmap
*
* @param ctx
* @param diskCachePath
* 磁盘缓存路径
* @param memoryCacheSize
* 内存缓存大小
* @return
*/
public static FinalBitmap create(Context ctx, String diskCachePath, int memoryCacheSize) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.configDiskCachePath(diskCachePath);
mFinalBitmap.configMemoryCacheSize(memoryCacheSize);
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 创建finalBitmap
*
* @param ctx
* @param diskCachePath
* 磁盘缓存路径
* @param memoryCacheSizePercent
* 缓存大小在当前进程的百分比(0.05-0.8之间)
* @param threadSize
* 线程并发数量
* @return
*/
public static FinalBitmap create(Context ctx, String diskCachePath, float memoryCacheSizePercent, int threadSize) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.configDiskCachePath(diskCachePath);
mFinalBitmap.configBitmapLoadThreadSize(threadSize);
mFinalBitmap.configMemoryCachePercent(memoryCacheSizePercent);
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 创建finalBitmap
*
* @param ctx
* @param diskCachePath
* 磁盘缓存路径
* @param memoryCacheSize
* 内存缓存大小
* @param threadSize
* 线程并发数量
* @return
*/
public static FinalBitmap create(Context ctx, String diskCachePath, int memoryCacheSize, int threadSize) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.configDiskCachePath(diskCachePath);
mFinalBitmap.configBitmapLoadThreadSize(threadSize);
mFinalBitmap.configMemoryCacheSize(memoryCacheSize);
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 创建finalBitmap
*
* @param ctx
* @param diskCachePath
* 磁盘缓存路径
* @param memoryCacheSizePercent
* 缓存大小在当前进程的百分比(0.05-0.8之间)
* @param diskCacheSize
* 磁盘缓存大小
* @param threadSize
* 线程并发数量
* @return
*/
public static FinalBitmap create(Context ctx, String diskCachePath, float memoryCacheSizePercent, int diskCacheSize, int threadSize) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.configDiskCachePath(diskCachePath);
mFinalBitmap.configBitmapLoadThreadSize(threadSize);
mFinalBitmap.configMemoryCachePercent(memoryCacheSizePercent);
mFinalBitmap.configDiskCacheSize(diskCacheSize);
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 创建finalBitmap
*
* @param ctx
* @param diskCachePath
* 磁盘缓存路径
* @param memoryCacheSize
* 内存缓存大小
* @param diskCacheSize
* 磁盘缓存大小
* @param threadSize
* 线程并发数量
* @return
*/
public static FinalBitmap create(Context ctx, String diskCachePath, int memoryCacheSize, int diskCacheSize, int threadSize) {
if (mFinalBitmap == null) {
mFinalBitmap = new FinalBitmap(ctx.getApplicationContext());
mFinalBitmap.configDiskCachePath(diskCachePath);
mFinalBitmap.configBitmapLoadThreadSize(threadSize);
mFinalBitmap.configMemoryCacheSize(memoryCacheSize);
mFinalBitmap.configDiskCacheSize(diskCacheSize);
mFinalBitmap.init();
}
return mFinalBitmap;
}
/**
* 设置图片正在加载的时候显示的图片
*
* @param bitmap
*/
public FinalBitmap configLoadingImage(Bitmap bitmap) {
mConfig.defaultDisplayConfig.setLoadingBitmap(bitmap);
return this;
}
/**
* 设置图片正在加载的时候显示的图片
*/
public FinalBitmap configLoadingImage(int resId) {
mConfig.defaultDisplayConfig.setLoadingBitmap(BitmapFactory.decodeResource(mContext.getResources(), resId));
return this;
}
/**
* 设置图片加载失败时候显示的图片
*
* @param bitmap
*/
public FinalBitmap configLoadfailImage(Bitmap bitmap) {
mConfig.defaultDisplayConfig.setLoadfailBitmap(bitmap);
return this;
}
/**
* 设置图片加载失败时候显示的图片
*
* @param resId
*/
public FinalBitmap configLoadfailImage(int resId) {
mConfig.defaultDisplayConfig.setLoadfailBitmap(BitmapFactory.decodeResource(mContext.getResources(), resId));
return this;
}
/**
* 配置默认图片的小的高度
*
* @param bitmapHeight
*/
public FinalBitmap configBitmapMaxHeight(int bitmapHeight) {
mConfig.defaultDisplayConfig.setBitmapHeight(bitmapHeight);
return this;
}
/**
* 配置默认图片的小的宽度
*/
public FinalBitmap configBitmapMaxWidth(int bitmapWidth) {
mConfig.defaultDisplayConfig.setBitmapWidth(bitmapWidth);
return this;
}
/**
* 设置下载器,比如通过ftp或者其他协议去网络读取图片的时候可以设置这项
*
* @param downlader
* @return
*/
public FinalBitmap configDownlader(Downloader downlader) {
mConfig.downloader = downlader;
return this;
}
/**
* 设置显示器,比如在显示的过程中显示动画等
*
* @param displayer
* @return
*/
public FinalBitmap configDisplayer(Displayer displayer) {
mConfig.displayer = displayer;
return this;
}
/**
* 配置磁盘缓存路径
*
* @param strPath
* @return
*/
private FinalBitmap configDiskCachePath(String strPath) {
if (!TextUtils.isEmpty(strPath)) {
mConfig.cachePath = strPath;
}
return this;
}
/**
* 配置内存缓存大小 大于2MB以上有效
*
* @param size
* 缓存大小
*/
private FinalBitmap configMemoryCacheSize(int size) {
mConfig.memCacheSize = size;
return this;
}
/**
* 设置应缓存的在APK总内存的百分比,优先级大于configMemoryCacheSize
*
* @param percent
* 百分比,值的范围是在 0.05 到 0.8之间
*/
private FinalBitmap configMemoryCachePercent(float percent) {
mConfig.memCacheSizePercent = percent;
return this;
}
/**
* 设置磁盘缓存大小 5MB 以上有效
*
* @param size
*/
private FinalBitmap configDiskCacheSize(int size) {
mConfig.diskCacheSize = size;
return this;
}
/**
* 设置加载图片的线程并发数量
*
* @param size
*/
private FinalBitmap configBitmapLoadThreadSize(int size) {
if (size >= 1)
mConfig.poolSize = size;
return this;
}
/**
* 这个方法必须被调用后 FinalBitmap 配置才能有效
*
* @return
*/
private FinalBitmap init() {
mConfig.init();
BitmapCache.ImageCacheParams imageCacheParams = new BitmapCache.ImageCacheParams(mConfig.cachePath);
if (mConfig.memCacheSizePercent > 0.05 && mConfig.memCacheSizePercent < 0.8) {
imageCacheParams.setMemCacheSizePercent(mContext, mConfig.memCacheSizePercent);
} else {
if (mConfig.memCacheSize > 1024 * 1024 * 2) {
imageCacheParams.setMemCacheSize(mConfig.memCacheSize);
} else {
// 设置默认的内存缓存大小
imageCacheParams.setMemCacheSizePercent(mContext, 0.3f);
}
}
if (mConfig.diskCacheSize > 1024 * 1024 * 5)
imageCacheParams.setDiskCacheSize(mConfig.diskCacheSize);
mImageCache = new BitmapCache(imageCacheParams);
bitmapLoadAndDisplayExecutor = Executors.newFixedThreadPool(mConfig.poolSize, new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
// 设置线程的优先级别,让线程先后顺序执行(级别越高,抢到cpu执行的时间越多)
t.setPriority(Thread.NORM_PRIORITY - 1);
return t;
}
});
new CacheExecutecTask().execute(CacheExecutecTask.MESSAGE_INIT_DISK_CACHE);
return this;
}
// //////////////////////// config method
// end////////////////////////////////////
public void display(ImageView imageView, String uri) {
// Log.i("fb", "原来图片地址-->" + uri);
if (uri != null) {
doDisplay(imageView, uri, null, false, false);
}
}
public void displayRound(ImageView imageView, String uri, BitmapDisplayConfig displayConfig, boolean round) {
doDisplay(imageView, uri, displayConfig, false, round);
}
/**
* WIFI状态下加载大图片 uri小图片 bigUri大图片
*
* @param imageView
* @param uri
* @param bigUrl
*/
public void display(ImageView imageView, String uri, String bigUrl) {
String path = BitmapCommonUtils.getDiskCacheDir(mContext, Pluto.FINAL_BIMAP_SAVE_PATH).getAbsolutePath() + "/" + FileNameGenerator.generator(bigUrl) + ".0";
doDisplay(imageView, uri, null, false, false);
}
/**
* 判断内容是否少于1G
* @return
*/
private boolean isLessMemory() {
if (memerySize==0) {
String str1 = "/proc/meminfo";// 系统内存信息文件
String str2;
String[] arrayOfString;
long initial_memory = 0;
try {
FileReader localFileReader = new FileReader(str1);
BufferedReader localBufferedReader = new BufferedReader(
localFileReader, 8192);
str2 = localBufferedReader.readLine();// 读取meminfo第一行,系统总内存大小
arrayOfString = str2.split("\\s+");
initial_memory = Math.abs(Integer.valueOf(arrayOfString[1]).intValue() * 1024);// 获得系统总内存,单位是KB,乘以1024转换为Byte
localBufferedReader.close();
//Log.i("memery", "menery--->"+(float)initial_memory/1024/1024/1024);
memerySize = initial_memory;
if ((float)memerySize/1024/1024/1024>1) {
return false;
}else{
return true;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}else{
if ((float)memerySize/1024/1024/1024>1) {
return false;
}else{
return true;
}
}
}
/**
* 等比例缩放
*
* @param imageView
* @param uri
* @param scale
*/
public void displayScale(ImageView imageView, String uri, boolean scale) {
doDisplay(imageView, uri, null, scale, false);
}
/**
* 等比例缩放
*
* @param imageView
* @param uri
* @param scale
*/
public void displayScale(ImageView imageView, String uri, BitmapDisplayConfig displayConfig, boolean scale) {
doDisplay(imageView, uri, displayConfig, scale, false);
}
public void display(ImageView imageView, String uri, int imageWidth, int imageHeight) {
BitmapDisplayConfig displayConfig = configMap.get(imageWidth + "_" + imageHeight);
if (displayConfig == null) {
displayConfig = getDisplayConfig();
displayConfig.setBitmapHeight(imageHeight);
displayConfig.setBitmapWidth(imageWidth);
configMap.put(imageWidth + "_" + imageHeight, displayConfig);
}
doDisplay(imageView, uri, displayConfig, false, false);
}
public void display(ImageView imageView, String uri, Bitmap loadingBitmap) {
BitmapDisplayConfig displayConfig = configMap.get(String.valueOf(loadingBitmap));
if (displayConfig == null) {
displayConfig = getDisplayConfig();
displayConfig.setLoadingBitmap(loadingBitmap);
configMap.put(String.valueOf(loadingBitmap), displayConfig);
}
doDisplay(imageView, uri, displayConfig, false, false);
}
public void display(ImageView imageView, String uri, Bitmap loadingBitmap, Bitmap laodfailBitmap) {
BitmapDisplayConfig displayConfig = configMap.get(String.valueOf(loadingBitmap) + "_" + String.valueOf(laodfailBitmap));
if (displayConfig == null) {
displayConfig = getDisplayConfig();
displayConfig.setLoadingBitmap(loadingBitmap);
displayConfig.setLoadfailBitmap(laodfailBitmap);
configMap.put(String.valueOf(loadingBitmap) + "_" + String.valueOf(laodfailBitmap), displayConfig);
}
doDisplay(imageView, uri, displayConfig, false, false);
}
public void display(ImageView imageView, String uri, int imageWidth, int imageHeight, Bitmap loadingBitmap, Bitmap laodfailBitmap) {
BitmapDisplayConfig displayConfig = configMap.get(imageWidth + "_" + imageHeight + "_" + String.valueOf(loadingBitmap) + "_" + String.valueOf(laodfailBitmap));
if (displayConfig == null) {
displayConfig = getDisplayConfig();
displayConfig.setBitmapHeight(imageHeight);
displayConfig.setBitmapWidth(imageWidth);
displayConfig.setLoadingBitmap(loadingBitmap);
displayConfig.setLoadfailBitmap(laodfailBitmap);
configMap.put(imageWidth + "_" + imageHeight + "_" + String.valueOf(loadingBitmap) + "_" + String.valueOf(laodfailBitmap), displayConfig);
}
doDisplay(imageView, uri, displayConfig, true, false);
}
public void display(ImageView imageView, String uri, BitmapDisplayConfig config) {
doDisplay(imageView, uri, config, false, false);
}
private void doDisplay(ImageView imageView, String uri, BitmapDisplayConfig displayConfig, boolean scale, boolean round) {
if (TextUtils.isEmpty(uri) || imageView == null) {
return;
}
if (displayConfig == null)
displayConfig = mConfig.defaultDisplayConfig;
Bitmap bitmap = null;
if (mImageCache != null) {
bitmap = mImageCache.getBitmapFromMemCache(uri);
}
if (bitmap != null) {
if (round) {
bitmap = PhotoUtil.toRoundBitmap(bitmap);
}
imageView.setImageBitmap(bitmap);
} else if (checkImageTask(uri, imageView)) {
final BitmapLoadAndDisplayTask task = new BitmapLoadAndDisplayTask(imageView, displayConfig);
// 设置默认图片
final AsyncDrawable asyncDrawable = new AsyncDrawable(mContext.getResources(), displayConfig.getLoadingBitmap(), task);
imageView.setImageDrawable(asyncDrawable);
task.executeOnExecutor(bitmapLoadAndDisplayExecutor, uri, scale, round);
}
}
private HashMap<String, BitmapDisplayConfig> configMap = new HashMap<String, BitmapDisplayConfig>();
private BitmapDisplayConfig getDisplayConfig() {
BitmapDisplayConfig config = new BitmapDisplayConfig();
config.setAnimation(mConfig.defaultDisplayConfig.getAnimation());
config.setAnimationType(mConfig.defaultDisplayConfig.getAnimationType());
config.setBitmapHeight(mConfig.defaultDisplayConfig.getBitmapHeight());
config.setBitmapWidth(mConfig.defaultDisplayConfig.getBitmapWidth());
config.setLoadfailBitmap(mConfig.defaultDisplayConfig.getLoadfailBitmap());
config.setLoadingBitmap(mConfig.defaultDisplayConfig.getLoadingBitmap());
return config;
}
private void initDiskCacheInternal() {
if (mImageCache != null) {
mImageCache.initDiskCache();
}
if (mConfig != null && mConfig.bitmapProcess != null) {
mConfig.bitmapProcess.initHttpDiskCache();
}
}
private void clearCacheInternal() {
if (mImageCache != null) {
mImageCache.clearCache();
}
if (mConfig != null && mConfig.bitmapProcess != null) {
mConfig.bitmapProcess.clearCacheInternal();
}
}
private void clearMemoryCache() {
if (mImageCache != null) {
mImageCache.clearMemoryCache();
}
}
private void flushCacheInternal() {
if (mImageCache != null) {
mImageCache.flush();
}
if (mConfig != null && mConfig.bitmapProcess != null) {
mConfig.bitmapProcess.flushCacheInternal();
}
}
private void closeCacheInternal() {
if (mImageCache != null) {
mImageCache.close();
mImageCache = null;
}
if (mConfig != null && mConfig.bitmapProcess != null) {
mConfig.bitmapProcess.clearCacheInternal();
}
}
/**
* 网络加载bitmap
*
* @return
*/
private Bitmap processBitmap(String uri, BitmapDisplayConfig config) {
if (mConfig != null && mConfig.bitmapProcess != null) {
return mConfig.bitmapProcess.processBitmap(uri, config);
}
return null;
}
public void setExitTasksEarly(boolean exitTasksEarly) {
mExitTasksEarly = exitTasksEarly;
}
/**
* activity onResume的时候调用这个方法,让加载图片线程继续
*/
public void onResume() {
setExitTasksEarly(false);
}
/**
* activity onPause的时候调用这个方法,让线程暂停
*/
public void onPause() {
setExitTasksEarly(true);
flushCache();
}
/**
* activity onDestroy的时候调用这个方法,释放缓存
*/
public void onDestroy() {
closeCache();
}
/**
* 清除缓存
*/
public void clearAllCache() {
new CacheExecutecTask().execute(CacheExecutecTask.MESSAGE_CLEAR);
}
/**
* 清除缓存
*/
public void clearMemeoryCache() {
new CacheExecutecTask().execute(CacheExecutecTask.MESSAGE_CLEAR_MEMORY);
}
/**
* 刷新缓存
*/
public void flushCache() {
new CacheExecutecTask().execute(CacheExecutecTask.MESSAGE_FLUSH);
}
/**
* 关闭缓存
*/
public void closeCache() {
new CacheExecutecTask().execute(CacheExecutecTask.MESSAGE_CLOSE);
}
/**
* 退出正在加载的线程,程序退出的时候调用词方法
*
* @param exitTasksEarly
*/
public void exitTasksEarly(boolean exitTasksEarly) {
mExitTasksEarly = exitTasksEarly;
if (exitTasksEarly)
pauseWork(false);// 让暂停的线程结束
}
/**
* 暂停正在加载的线程,监听listview或者gridview正在滑动的时候条用词方法
*
* @param pauseWork
* true停止暂停线程,false继续线程
*/
public void pauseWork(boolean pauseWork) {
synchronized (mPauseWorkLock) {
mPauseWork = pauseWork;
if (!mPauseWork) {
mPauseWorkLock.notifyAll();
}
}
}
private static BitmapLoadAndDisplayTask getBitmapTaskFromImageView(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
/**
* 检测 imageView中是否已经有线程在运行
*
* @param data
* @param imageView
* @return true 没有 false 有线程在运行了
*/
public static boolean checkImageTask(Object data, ImageView imageView) {
final BitmapLoadAndDisplayTask bitmapWorkerTask = getBitmapTaskFromImageView(imageView);
if (bitmapWorkerTask != null) {
final Object bitmapData = bitmapWorkerTask.data;
if (bitmapData == null || !bitmapData.equals(data)) {
bitmapWorkerTask.cancel(true);
} else {
// 同一个线程已经在执行
return false;
}
}
return true;
}
public static BitmapCache getBitmapCache(){
return mImageCache;
}
private static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapLoadAndDisplayTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap, BitmapLoadAndDisplayTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference = new WeakReference<BitmapLoadAndDisplayTask>(bitmapWorkerTask);
}
public BitmapLoadAndDisplayTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
/**
* @author michael Young (www.YangFuhai.com)
* @version 1.0
* @title 缓存操作的异步任务
* @description 操作缓存
* @company 探索者网络工作室(www.tsz.net)
* @created 2012-10-28
*/
private class CacheExecutecTask extends AsyncTask<Object, Void, Void> {
public static final int MESSAGE_CLEAR = 0;
public static final int MESSAGE_INIT_DISK_CACHE = 1;
public static final int MESSAGE_FLUSH = 2;
public static final int MESSAGE_CLOSE = 3;
public static final int MESSAGE_CLEAR_MEMORY = 4;
@Override
protected Void doInBackground(Object... params) {
switch ((Integer) params[0]) {
case MESSAGE_CLEAR:
clearCacheInternal();
break;
case MESSAGE_INIT_DISK_CACHE:
initDiskCacheInternal();
break;
case MESSAGE_FLUSH:
clearMemoryCache();
flushCacheInternal();
break;
case MESSAGE_CLOSE:
clearMemoryCache();
closeCacheInternal();
break;
case MESSAGE_CLEAR_MEMORY:
clearMemoryCache();
break;
}
return null;
}
}
/**
* bitmap下载显示的线程
*
* @author michael yang
*/
private class BitmapLoadAndDisplayTask extends AsyncTask<Object, Void, Bitmap> {
private Object data;
private final WeakReference<ImageView> imageViewReference;
private final BitmapDisplayConfig displayConfig;
boolean scale = false;
boolean round = false;
public BitmapLoadAndDisplayTask(ImageView imageView, BitmapDisplayConfig config) {
imageViewReference = new WeakReference<ImageView>(imageView);
displayConfig = config;
}
@Override
protected Bitmap doInBackground(Object... params) {
data = params[0];
final String dataString = String.valueOf(data);
Bitmap bitmap = null;
if (params.length > 1) {
scale = (Boolean) params[1];
}
if (params.length > 2) {
round = (Boolean) params[2];
}
synchronized (mPauseWorkLock) {
while (mPauseWork && !isCancelled()) {
try {
mPauseWorkLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (mImageCache != null && !isCancelled() && getAttachedImageView() != null && !mExitTasksEarly) {
bitmap = mImageCache.getBitmapFromDiskCache(dataString);
LogUtils.info("finalbitmap", "mImageCache != null && !isCancelled()");
}
if (bitmap == null && !isCancelled() && getAttachedImageView() != null && !mExitTasksEarly) {
bitmap = processBitmap(dataString, displayConfig);
if (bitmap != null) {
if (scale) {
int widthScrean = mContext.getApplicationContext().getResources().getDisplayMetrics().widthPixels;
int imageOrigWidth = bitmap.getWidth();
int imageOrigHeigh = bitmap.getHeight();
LogUtils.info("finalbitmap", "宽度-->" + imageOrigWidth + ",--->" + imageOrigHeigh);
int reSizeHeigh = (int) (widthScrean * ((double) imageOrigHeigh / (double) imageOrigWidth));
LogUtils.info("finalbitmap", "1宽度-->" + widthScrean + ",---1>" + reSizeHeigh);
bitmap = Bitmap.createScaledBitmap(bitmap, widthScrean, reSizeHeigh, true);
}
}
}
if (bitmap != null && mImageCache != null) {
mImageCache.addBitmapToCache(dataString, bitmap);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled() || mExitTasksEarly) {
bitmap = null;
}
// 判断线程和当前的imageview是否是匹配
final ImageView imageView = getAttachedImageView();
if (bitmap != null && imageView != null) {
if (round) {
bitmap = PhotoUtil.toRoundBitmap(bitmap);
}
mConfig.displayer.loadCompletedisplay(imageView, bitmap, displayConfig);
} else if (bitmap == null && imageView != null) {
mConfig.displayer.loadFailDisplay(imageView, displayConfig.getLoadfailBitmap());
}
}
@Override
protected void onCancelled(Bitmap bitmap) {
super.onCancelled(bitmap);
synchronized (mPauseWorkLock) {
mPauseWorkLock.notifyAll();
}
}
/**
* 获取线程匹配的imageView,防止出现闪动的现象
*
* @return
*/
private ImageView getAttachedImageView() {
final ImageView imageView = imageViewReference.get();
final BitmapLoadAndDisplayTask bitmapWorkerTask = getBitmapTaskFromImageView(imageView);
if (this == bitmapWorkerTask) {
return imageView;
}
return null;
}
}
private LoadFinishListener loadFinishListener;
public interface LoadFinishListener {
public void loadFinish(ImageView imageView);
}
public void display(ImageView imageView, String uri, LoadFinishListener listener) {
if (listener != null) {
loadFinishListener = listener;
}
if (uri != null) {
doDisplay(imageView, uri, null, false, false);
}
}
/**
* @author michael Young (www.YangFuhai.com)
* @version 1.0
* @title 配置信息
* @description FinalBitmap的配置信息
* @company 探索者网络工作室(www.tsz.net)
* @created 2012-10-28
*/
private class FinalBitmapConfig {
public String cachePath;
public Displayer displayer;
public Downloader downloader;
public BitmapProcess bitmapProcess;
public BitmapDisplayConfig defaultDisplayConfig;
public float memCacheSizePercent;// 缓存百分比,android系统分配给每个apk内存的大小
public int memCacheSize;// 内存缓存百分比
public int diskCacheSize;// 磁盘百分比
public int poolSize = 3;// 默认的线程池线程并发数量
public int originalDiskCacheSize = 30 * 1024 * 1024;// 50MB
public FinalBitmapConfig(Context context) {
defaultDisplayConfig = new BitmapDisplayConfig();
defaultDisplayConfig.setAnimation(null);
defaultDisplayConfig.setAnimationType(BitmapDisplayConfig.AnimationType.fadeIn);
// 设置图片的显示最大尺寸(为屏幕的大小,默认为屏幕宽度的1/3)
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
int defaultWidth = (int) Math.floor(displayMetrics.widthPixels / 4);
defaultDisplayConfig.setBitmapHeight(defaultWidth);
defaultDisplayConfig.setBitmapWidth(defaultWidth);
}
public void init() {
if (downloader == null)
downloader = new SimpleHttpDownloader();
if (displayer == null)
displayer = new SimpleDisplayer();
bitmapProcess = new BitmapProcess(downloader, cachePath, originalDiskCacheSize);
}
}
}