package com.jerehedu.cache;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;
/**
* 异步加载图片资源
*
*/
public class AsyncImageLoader{
private MemoryCache mMemoryCache;//内存缓存
private FileCache mFileCache;//文件缓存
private ExecutorService mExecutorService;//线程池
private Map<ImageView, String> mImageViews = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());//记录已经加载图片的ImageView
private List<LoadPhotoTask> mTaskQueue = new ArrayList<LoadPhotoTask>();//保存正在加载图片的url
/**
* 默认采用一个大小为5的线程池
* @param context
* @param memoryCache 所采用的高速缓存
* @param fileCache 所采用的文件缓存
*/
public AsyncImageLoader(Context context, MemoryCache memoryCache, FileCache fileCache) {
mMemoryCache = memoryCache;
mFileCache = fileCache;
mExecutorService = Executors.newFixedThreadPool(5);//建立一个容量为5的固定尺寸的线程池(最大正在运行的线程数量)
}
/**
* 根据url加载相应的图片
* @param url
* @return 如果缓存里有则直接返回,如果没有则异步从文件或网络端获取
*/
public Bitmap loadBitmap(ImageView imageView, String url) {
mImageViews.put(imageView, url);//先将ImageView记录到Map中,表示该ui已经执行过图片加载了
Bitmap bitmap = mMemoryCache.get(url);//先从一级缓存中获取图片
if(bitmap == null) {
enquequeLoadPhoto(url, imageView);
}
return bitmap;
}
/**
* 加入图片下载队列
* @param url
*/
private void enquequeLoadPhoto(String url, ImageView imageView) {
//如果任务已经存在,则不重新添加
if(isTaskExisted(url))
return;
LoadPhotoTask task = new LoadPhotoTask(url, imageView);
synchronized (mTaskQueue) {
mTaskQueue.add(task);//将任务添加到队列中
}
mExecutorService.execute(task);//向线程池中提交任务,如果没有达到上限(5),则运行否则被阻塞
}
/**
* 判断下载队列中是否已经存在该任务
* @param url
* @return
*/
private boolean isTaskExisted(String url) {
if(url == null)
return false;
synchronized (mTaskQueue) {
int size = mTaskQueue.size();
for(int i=0; i<size; i++) {
LoadPhotoTask task = mTaskQueue.get(i);
if(task != null && task.getUrl().equals(url))
return true;
}
}
return false;
}
/**
* 从缓存文件或者网络端获取图片
* @param url
*/
private Bitmap getBitmapByUrl(String url) {
File f = mFileCache.getFile(url);//获得缓存图片路径
Bitmap b = ImageUtil.decodeFile(f);//获得文件的Bitmap信息
if (b != null)//不为空表示获得了缓存的文件
return b;
return ImageUtil.loadBitmapFromWeb(url, f);//同网络获得图片
}
/**
* 判断该ImageView是否已经加载过图片了(可用于判断是否需要进行加载图片)
* @param imageView
* @param url
* @return
*/
private boolean imageViewReused(ImageView imageView, String url) {
String tag = mImageViews.get(imageView);
if (tag == null || !tag.equals(url))
return true;
return false;
}
private void removeTask(LoadPhotoTask task) {
synchronized (mTaskQueue) {
mTaskQueue.remove(task);
}
}
class LoadPhotoTask implements Runnable {
private String url;
private ImageView imageView;
LoadPhotoTask(String url, ImageView imageView) {
this.url = url;
this.imageView = imageView;
}
@Override
public void run() {
if (imageViewReused(imageView, url)) {//判断ImageView是否已经被复用
removeTask(this);//如果已经被复用则删除任务
return;
}
Bitmap bmp = getBitmapByUrl(url);//从缓存文件或者网络端获取图片
mMemoryCache.put(url, bmp);//将图片放入到一级缓存中
if (!imageViewReused(imageView, url)) {//若ImageView未加图片则在ui线程中显示图片
BitmapDisplayer bd = new BitmapDisplayer(bmp, imageView, url);//含有run()实现设置ImageView图片的组件
Activity a = (Activity) imageView.getContext();
a.runOnUiThread(bd);//在UI线程调用bd组件的run方法,实现为ImageView控件加载图片
}
removeTask(this);//从队列中移除任务
}
public String getUrl() {
return url;
}
}
/**
*
*由UI线程中执行该组件的run方法
*/
class BitmapDisplayer implements Runnable {
private Bitmap bitmap;
private ImageView imageView;
private String url;
public BitmapDisplayer(Bitmap b, ImageView imageView, String url) {
bitmap = b;
this.imageView = imageView;
this.url = url;
}
public void run() {
if (imageViewReused(imageView, url))
return;
if (bitmap != null)
imageView.setImageBitmap(bitmap);
}
}
/**
* 释放资源
*/
public void destroy() {
mMemoryCache.clear();
mMemoryCache = null;
mImageViews.clear();
mImageViews = null;
mTaskQueue.clear();
mTaskQueue = null;
mExecutorService.shutdown();
mExecutorService = null;
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
Android开发中批量异步加载网络图片的方法
共45个文件
class:18个
java:8个
xml:6个
需积分: 9 8 下载量 119 浏览量
2018-04-03
21:13:31
上传
评论
收藏 95KB RAR 举报
温馨提示
1、采用异步加载的机制。 2、编写自定义适配器。 3、本例中传的是数组,可根据个人需要传list集合等。
资源推荐
资源详情
资源评论
收起资源包目录
LoadURLImage.rar (45个子文件)
LoadURLImage
CacheImage
bin
classes.dex 15KB
res
crunch
drawable
default_big.png 3KB
icon.png 2KB
dexedLibs
classes
com
jereh
view
MainActivity.class 2KB
BuildConfig.class 337B
R$layout.class 419B
R$id.class 427B
R$drawable.class 423B
R$attr.class 328B
ListViewAdapter.class 4KB
R.class 547B
ListViewAdapter$ViewHolder.class 741B
R$string.class 415B
R$style.class 419B
jerehedu
cache
MemoryCache.class 2KB
AsyncImageLoader$BitmapDisplayer.class 1KB
FileCache.class 2KB
MemoryCache$1.class 1KB
ImageUtil.class 3KB
AsyncImageLoader.class 5KB
AsyncImageLoader$LoadPhotoTask.class 2KB
resources.ap_ 9KB
LazyList.apk 20KB
CacheImage.apk 19KB
AndroidManifest.xml 1KB
res
drawable-ldpi
drawable-hdpi
drawable-xhdpi
drawable
default_big.png 9KB
icon.png 3KB
values
strings.xml 173B
styles.xml 695B
drawable-mdpi
layout
item.xml 653B
activity_main.xml 465B
assets
gen
com
jereh
view
BuildConfig.java 156B
R.java 2KB
.settings
org.eclipse.jdt.core.prefs 177B
src
com
jereh
view
ListViewAdapter.java 2KB
MainActivity.java 1KB
jerehedu
cache
MemoryCache.java 2KB
FileCache.java 1KB
ImageUtil.java 4KB
AsyncImageLoader.java 5KB
.project 846B
.classpath 475B
.gitignore 10B
project.properties 377B
AndroidManifest.xml 1KB
共 45 条
- 1
资源评论
北极熊的微笑
- 粉丝: 198
- 资源: 17
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功