对于从网络上加载大量的图片到Listview中在应用中是特别常见的,但是对于内存缓存来说,无论做的再好,当应用程序销毁时,图片也就销毁。因此把listview中从网络中获取的图片保存到本地,一方面使应用变得流畅,另一方面节省流量。对于这样的需求Universal_image_loader天生做这样的工作。
可能用到的相关知识:
1、内存缓存与sd卡缓存
- 内存缓存:把从网络加载的图片缓存到内存中,当再次请求时,先从内存中获取,如果内存中没有,则从网络获取。
- sd卡缓存:加载图片时,先从sd卡中获取,如果sd卡中没有,则查找内存缓存,如果也没有,从网络获取
2、线程,线程池的相关知识
- 线程的生命周期包括创建,就绪,运行,阻塞,销毁阶段。如果我们处理的任务数目较少,可以自己创建多个线程来处理相应的任务。但是如果处理的任务数目相当多,由于创建线程,销毁线程本身就有大量的工作,因此当任务数量比较多时,就可以采用线程池。
- 当采用线程池的时候,我们可以规定线程池,线程的数量,当一个线程执行完一个任务的时候,会接着执行另一个任务,如果这个线程发生异常,则由另一个线程池中的线程来代替。
- 如果任务数量多于线程数量,则没有完成的任务处于等待阶段。
- 线程池的组成部分:
1、线程池管理器(ThreadPoolManager):用于创建并管理线程池
2、工作线程(WorkThread): 线程池中线程
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。
4、任务队列:用于存放没有处理的任务。提供一种缓冲机制。
3、线程的优先级
- 线程的优先级,是指线程的先后执行顺序。在java中通过.setPriority(); 来设置线程的级别。
- Java线程的优先级是一个整数,其取值范围是1 - 10 ,数值越大,优先级别越高。
- Thread源代码里对NORM_PRIORITY (数值为5) 的注释是“线程默认的优先级“。
4、image_loader使用中常用的类分析
ImageLoaderConfiguration做的是一些全局配置,主要有线程类、缓存大小、磁盘大小、图片下载与解析、日志方面的配置。
ImageLoader是具体下载图片,缓存图片,显示图片的具体执行类。
DisplayImageOptions用于显示每一个的Imageloader根据网络图片的状态(空白、下载错误、正在下载)显示对应的图片,是否将缓存加载到磁盘上,下载完后对图片进行怎么样的处理。
使用universal-image-loader加载图片代码如下:
在Application中做的全局初始化工作:
public class MyApplication extends Application {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
initImageLoader(getApplicationContext());
}
private void initImageLoader(Context context) {
// TODO Auto-generated method stub
//缓存文件名称:当删除应用时,缓存文件也删除;
File cacheDir=StorageUtils.getCacheDirectory(getApplicationContext());
//初始化imageloaderConfiguration配置;
ImageLoaderConfiguration config=new ImageLoaderConfiguration.Builder(context)
//设置线程优先级;默认级别是5,在这里可以设置一个,3或者4级别都行。
.threadPriority(Thread.NORM_PRIORITY-1)
.denyCacheImageMultipleSizesInMemory()
.discCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.discCache(new UnlimitedDiscCache(cacheDir))
//设置在缓存sd卡上为5M,当大于5M用LRU算法清理
.discCacheSize(5*1024*1024)
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.discCacheFileCount(100)
.writeDebugLogs()
.build();
ImageLoader.getInstance().init(config);
}
}
在ImageLoaderConfiguration中的常用设置:
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.taskExecutor(...)//添加个线程池,进行下载
.taskExecutorForCachedImages(...)//添加线程池缓存图片;
.threadPoolSize(4) // 线程池线程数量设置;
.threadPriority(Thread.NORM_PRIORITY - 1) // 设置线程的优先级
.tasksProcessingOrder(QueueProcessingType.FIFO) //设置图片下载和显示的工作队列排序
.denyCacheImageMultipleSizesInMemory()//当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))//设置内存缓存,使用lru算法管理;
.memoryCacheSize(2 * 1024 * 1024)//设置内存缓存的大小;
.memoryCacheSizePercentage(13) //设置内存缓存
.diskCache(new UnlimitedDiscCache(cacheDir)) //缓存没有限制;
.diskCacheSize(50 * 1024 * 1024)//设置缓存的大小
.diskCacheFileCount(100)//设置缓存文件的数量
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) //通过HashCode将url生成文件名
Madapter中的代码如下:
public class MyAdapter extends BaseAdapter {
private Context context;
private String[] images;
private ImageLoader imageLoader;
DisplayImageOptions options;
//对imageloading设置监听事件;
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
public MyAdapter(Context context, String[] images) {
this.context = context;
this.images = images;
imageLoader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisc(true)
.considerExifParams(true)
.displayer(new RoundedBitmapDisplayer(15))
.build();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return images.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
// TODO Auto-generated method stub
ViewHolder vh;
if (convertView == null) {
vh = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item,
null);
vh.imageview = (ImageView) convertView.findViewById(R.id.imageview);
vh.textview = (TextView) convertView.findViewById(R.id.textview);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
vh.textview.setText("item"+position);
imageLoader.displayImage(images[position], vh.imageview, options,
animateFirstListener);
return convertView;
}
static final class ViewHolder {
ImageView imageview;
TextView textview;
}
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
ImageView imageView = (ImageView) view;
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay) {
FadeInBitmapDisplayer.animate(imageView, 500);
displayedImages.add(imageUri);
}
}
}
}
DisplayImageOptions 中的常用设置:
DisplayImageOptionsoptions = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)//下载时间显示的图片
.showImageForEmptyUri(R.drawable.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.ic_launcher)//错误时候显示的图片
.cacheInMemory(true)//缓存到内存中
.cacheOnDisk(true)//缓存到sd卡中;
.displayer(new FadeInBitmapDisplayer(100))
.considerExifParams(true)
.displayer(new FadeInBitmapDisplayer(100))// 图片加载好后渐入的动画时间
.displayer(new RoundedBitmapDisplayer(1)).build();//设置图片的圆角显示;值越大,圆角的弧度就越大
Activity中的代码如下:
public class MainActivity extends ActionBarActivity {
private ListView listview;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview=(ListView) findViewById(R.id.listview);
adapter=new MyAdapter(this,Constants.images);
listview.setAdapter(adapter);
}
}
注意:1导jar包。
2.加权限。
3.在application节点中配置名称。
图片在sd卡上的缓存路径:sdcard/Android/data/包名/cache
运行app后,退出应用,关闭网络,再次进入,图片依然可以显示出来
Demo下载地址eclipse版
http://download.youkuaiyun.com/detail/androidxiaogang/9199847