本博客包含包含Android-Universal-Image-Loader 网络图片加载框架实现图片加载和结合universal-image-loader与LruCache来自定义缓存图片,可以设置缓存与不缓存。
Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。是个主流的应用,很多应用都有用到,如:天猫,淘宝等。
github源码下载:https://github.com/nostra13/Android-Universal-Image-Loader
Universal-Image-Loader.jar下载
效果图:
由效果图可以看到第一次加载和第二次加载是不一样的,第一次加载是从服务器端获取,其中将他缓存了下来,第二次加载时就会和第一次加载比较,相同的就从缓存中获取,新的图片则重新到服务器端获取,从而提高效率,减少用户流量。
代码:
Android-Universal-Image-Loader 直接加载的方式
private void showImg() {
imageLoader = ImageLoader.getInstance();
imageUrls = Images.imageThumbUrls;
// 使用DisplayImageOptions.Builder()创建DisplayImageOptions
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.mipmap.ic_launcher) // 设置图片下载期间显示的图片
.showImageForEmptyUri(R.mipmap.ic_launcher) // 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.mipmap.ic_launcher) // 设置图片加载或解码过程中发生错误显示的图片
.cacheInMemory(true) // 设置下载的图片是否缓存在内存中
.cacheOnDisk(true) // 设置下载的图片是否缓存在SD卡中
.displayer(new RoundedBitmapDisplayer(20)) // 设置成圆角图片
.build(); // 构建完成
}
imageLoader.displayImage(img[position], holder.image,options);
Android-Universal-Image-Loader结合LruCache
private ImageLoader mImageLoader;
private void initView() {
mImageLoader = ImageLoader.getInstance(3, ImageLoader.Type.LIFO);
/***
* 第一个参数:Url
* 第二个参数:图片实例
* 第三个参数:是否缓存
*
*/
mImageLoader.loadImage("", imageview1, true);
mImageLoader.loadImage("http://tnfs.tngou.net/image/info/150729/d9ae7426fef7f2d58c190cffab6ad5f7.png", imageview2, true);
mImageLoader.loadImage("http://tnfs.tngou.net/image/info/150729/c96da5303be57a916e62ca79ecb9930d.jpg", imageview3, true);
}
辅助类 (
注:辅助类想深入了解的可以看一下,想直接用的直接下载源码就OK了,博客提供代码不全)
/**
* 图片缓存的核心对象
*/
private LruCache<String, Bitmap> mLruCache;
private void init(int threadCount, Type type)
{
initBackThread();
// 获取我们应用的最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheMemory = maxMemory / 8;
mLruCache = new LruCache<String, Bitmap>(cacheMemory)
{
@Override
protected int sizeOf(String key, Bitmap value)
{
return value.getRowBytes() * value.getHeight();
}
};
// 创建线程池
mThreadPool = Executors.newFixedThreadPool(threadCount);
mTaskQueue = new LinkedList<Runnable>();
mType = type;
mSemaphoreThreadPool = new Semaphore(threadCount);
}
/**
* 初始化后台轮询线程
*/
private void initBackThread()
{
// 后台轮询线程
mPoolThread = new Thread()
{
@Override
public void run()
{
Looper.prepare();
mPoolThreadHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// 线程池去取出一个任务进行执行
mThreadPool.execute(getTask());
try
{
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e)
{
}
}
};
// 释放一个信号量
mSemaphorePoolThreadHandler.release();
Looper.loop();
};
};
mPoolThread.start();
}
public static ImageLoader getInstance()
{
if (mInstance == null)
{
synchronized (ImageLoader.class)
{
if (mInstance == null)
{
mInstance = new ImageLoader(DEAFULT_THREAD_COUNT, Type.LIFO);
}
}
}
return mInstance;
}
public static ImageLoader getInstance(int threadCount, Type type)
{
if (mInstance == null)
{
synchronized (ImageLoader.class)
{
if (mInstance == null)
{
mInstance = new ImageLoader(threadCount, type);
}
}
}
return mInstance;
}
/**
* 根据path为imageview设置图片
*
* @param path
* @param imageView
*/
public void loadImage(final String path, final ImageView imageView,
final boolean isFromNet)
{
imageView.setTag(path);
if (mUIHandler == null)
{
mUIHandler = new Handler()
{
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)
{
refreashBitmap(path, imageView, bm);
} else
{
addTask(buildTask(path, imageView, isFromNet));
}
}
好东西要大家一起分享,希望对大家有所帮助,呵呵!