您的位置:首页 > 其它

图片加载类ImageLoader

2015-12-14 17:33 253 查看
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.support.v4.view.ViewPager.LayoutParams;
import android.util.DisplayMetrics;
import android.widget.ImageView;

//图片加载类
public class ImageLoader {
private static ImageLoader mInstance;
//图片缓存的核心对象
private LruCache<String, Bitmap> mLruCache;
//线程池
private ExecutorService mThreadPool;
private static final int DEAFULT_THREAD_COUNT=1;
//队列的调度方式
private Type mType =Type.LIFO;
//任务队列
private LinkedList<Runnable> mTaskQueue;
//后台轮询线程
private Thread mPoolThread;
private Handler mPoolThreadHandler;
//UI线程中的Handler
private Handler mUIHandler;

private Semaphore mSemaphorePoolThreadHandler =new Semaphore(0);

private Semaphore mSemaphoreThreadPool;
public enum Type{
FIFO,LIFO;
}

private ImageLoader(int threadCount,Type type){
init(threadCount,type);
}

//初始化
private void init(int threadCount, Type type) {
//后台轮询线程
mPoolThread=new Thread(){
public void run(){
Looper.prepare();
mPoolThreadHandler =new Handler(){
@Override
public void handleMessage(Message msg) {
//线程池取出一个任务进行执行
mThreadPool.execute(getTask());

try {
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

};
//释放一个信号量
mSemaphorePoolThreadHandler.release();
Looper.loop();
}
};
mPoolThread.start();
//获取我们应用的最大可用内存
int maxMemory =(int) Runtime.getRuntime().maxMemory();
int cacheMemory =maxMemory/8;

mLruCache =new LruCache<String, Bitmap>(cacheMemory){
@Override
protected int sizeOf(String key, Bitmap value) {
// TODO Auto-generated method stub
return value.getRowBytes()*value.getHeight();
}
};
//创建线程池
mThreadPool =Executors.newFixedThreadPool(threadCount);
mTaskQueue =new LinkedList<Runnable>();
mType = type;

mSemaphoreThreadPool =new Semaphore(threadCount);
}
//从任务队列取出一个方法
private Runnable getTask() {
if(mType == Type.FIFO){
return mTaskQueue.removeFirst();
}else if(mType == Type.LIFO){
return mTaskQueue.removeLast();
}
return null;
}

public static ImageLoader getInstance(int i, Type lifo){
if(mInstance == null){
synchronized (ImageLoader.class) {
if(mInstance == null){
mInstance = new ImageLoader(DEAFULT_THREAD_COUNT,Type.LIFO);
}
}
}
return mInstance;
}
//根据path为imageview设置图片
public void loadImage(final String path, final ImageView imageView){
imageView.setTag(path);
if(mUIHandler==null){
mUIHandler =new Handler(){
@Override
public void handleMessage(Message msg) {
//获取得到的图片,为imageView的、回调设置图片
ImgBeanHolder holder =(ImgBeanHolder) msg.obj;
Bitmap bm =holder.bitmap;
ImageView imageView = holder.imageView;
String  path =holder.path;
//将path与getTag存储路径进行比较
if(imageView.getTag().toString().equals(path)){
imageView.setImageBitmap(bm);
}
}
};

}
//根据path在缓存中获取bitmap
Bitmap bm =getBitmapFromLruCache(path);

if(bm!=null){
reflash(path, imageView, bm);
}else{
addTasks(new Runnable() {

@Override
public void run() {
//加载图片
//图片的压缩
//1.获取图片所需要的大小
ImageSize imageSize=getImageViewSize(imageView);
//2.压缩图片
Bitmap bm=decodeSamledBitmapFromPath(path,imageSize.width,imageSize.height);
//3.把图片加入到缓存
addBitmapToLruCache(path,bm);

reflash(path, imageView, bm);

mSemaphoreThreadPool.release();
}

});
}

}
private void reflash(String path, ImageView imageView,
Bitmap bm) {
Message message =Message.obtain();
ImgBeanHolder holder =new ImgBeanHolder();
holder.bitmap=bm;
holder.path=path;
holder.imageView=imageView;
message.obj=holder;
mUIHandler.sendMessage(message);
}
//将图片加入缓存
protected void addBitmapToLruCache(String path, Bitmap bm) {
if(getBitmapFromLruCache(path)==null){
if(bm!=null){
mLruCache.put(path, bm);
}
}

}

//根据图片需要显示的宽和高对图片进行压缩
protected Bitmap decodeSamledBitmapFromPath(String path, int width,
int height) {
//获取图片的宽和高,并不把图片加载到内存中
BitmapFactory.Options options =new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize =caculateSampleSize(options,width,height);
//使用获取到的simplesize再次解析图片
options.inJustDecodeBounds=false;
Bitmap bitmap=BitmapFactory.decodeFile(path, options);
return bitmap;
}
//根据需求的宽和高以及图片实际的宽高计算SampleSize
private int caculateSampleSize(Options options, int reqWidth, int reqHeight) {
int width= options.outWidth;
int height =options.outHeight;

int inSampleSize=1;

if(width>reqWidth||height>reqHeight){
int widthRadio =Math.round(width*1.0f/reqWidth);
int heightRadio =Math.round(height*1.0f/reqHeight);

inSampleSize =Math.max(widthRadio, heightRadio);

}

return inSampleSize;
}

//根据ImageView获取适当的压缩的宽和高
protected ImageSize getImageViewSize(ImageView imageView) {
ImageSize imageSize =new ImageSize();

DisplayMetrics displayMetrics = imageView.getContext().getResources().getDisplayMetrics();
android.view.ViewGroup.LayoutParams lp =imageView.getLayoutParams();
//int width =(lp.width == LayoutParams.WRAP_CONTENT?0:imageView.getWidth());
int width=imageView.getWidth();//获取imageview的实际宽度
if(width<=0){
width =lp.width;//获取imageview在layout中声明的宽度
}
if(width<=0){
width=getImageViewFieldValue(imageView, "mMaxWidth");//检查最大值
}
if(width<=0){
width=displayMetrics.widthPixels;
}

int height=imageView.getHeight();//获取imageview的实际宽度
//int height =getImageViewFieldValue(imageView, "mMaxHeight");
if(height<=0){
width =lp.height;//获取imageview在layout中声明的宽度
}
if(height<=0){
height=getImageViewFieldValue(imageView, "mMaxHeight");//检查最大值
}
if(width<=0){
height=displayMetrics.heightPixels;
}

imageSize.width =width;
imageSize.height=height;
return imageSize;

}
//通过反射获取imageview的某个属性值
private static int getImageViewFieldValue(Object object,String fieldName){
int value=0;
try {
Field field =ImageView.class.getDeclaredField(fieldName);
field.setAccessible(true);

int fieldValue =field.getInt(object);
if(fieldValue>0&&fieldValue<Integer.MAX_VALUE){
value=fieldValue;
}
}  catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return value;
}

private synchronized void addTasks(Runnable runnable) {
mTaskQueue.add(runnable);
try {
if(mPoolThreadHandler==null)
mSemaphorePoolThreadHandler.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPoolThreadHandler.sendEmptyMessage(0x110);

}

//根据path在缓存中获取bitmap
private Bitmap getBitmapFromLruCache(String key) {

return mLruCache.get(key);
}
private class ImageSize{
int width;
int height;
}

private class ImgBeanHolder{
Bitmap bitmap;
ImageView imageView;
String path;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: