Android图片异步加载

开发 App 过程中,免不了要进行网络请求操作进行数据交换,比如下载图片,如果自己写一个下载图片的类进行操作的话,要考虑太多太多内容,必须线程池,内存溢出,图片磁盘缓存操作,图片内存缓存操作等等,相当麻烦。好在伟大的开源者们已经写好了一个比较完美的开源类库供大家使用 Android-Universal-Image-Loader ,这个类库已经被许多知名的软件所采用,当时我自己用这个开源类库的时候,百度了一大推,有查看了官方文档。现在把记录写下来供大家参考。

一、介绍:

Android-Universal-Image-Loader的目的是提供一个功能强大的,灵活的,高度可定制的图像加载,缓存和显示工具。它提供了大量的配置选项,并很好地控制图像加载和缓存。

类库的特点

l 多线程的图像加载(同步或异步)

l 灵活的图像加载配置选项(线程执行,下载,解码,内存和磁盘缓存,图像显示选项)

l 自定义每个显示图像的配置

l 在内存或磁盘上缓存(设备内存或SD卡)

l 监听加载进程(包括下载进度)
 
二、用法

从图中可看出,加载图片的时候一共分为三种情况:

postprocess Bitmap一步,实际就是对该图片进行处理,比如加水印,加圆角等等,该框架没有给出具体实现,默认为null,如有需要自己可以实现,所以分析的时候可以忽略)

1. 图片在内存中缓存:直接显示图片。

2. 图片在磁盘中缓存:先解码,再暂时缓存到内存中,最后显示。

3. 图片没有缓存:先下载,再是否缓存到磁盘和内存,最后显示。

() Include Library

官网下载依赖jar包,导入工程中libs文件夹下并添加到工程路径即可。

() 加权限

<manifest>

<!-- Include followingpermission if you load imagesfrom Internet -->

<uses-permissionandroid:name="android.permission.INTERNET" />

<!-- Include followingpermission if you want to cacheimages on SD card -->

<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE" />

...

</manifest>

(三)全局配置

全局配置我一般写个类继承application,然后在Mainfest文件中声明

public class MyApplication extends Application {

@Override

public void onCreate() {

// TODO Auto-generated methodstub

super.onCreate();

initImageLoader(getApplicationContext());

}

public static void initImageLoader(Contextcontext){

File cacheDir =StorageUtils.getCacheDirectory(context);

ImageLoaderConfiguration config =new ImageLoaderConfiguration.Builder(context)

.memoryCacheExtraOptions(480,800) // default = device screen dimensions

.diskCacheExtraOptions(480, 800,null)

// .taskExecutor(...)

//.taskExecutorForCachedImages(...)

.threadPoolSize(3) // default

.threadPriority(Thread.NORM_PRIORITY- 2) // default

.tasksProcessingOrder(QueueProcessingType.FIFO)// default

.denyCacheImageMultipleSizesInMemory()

// .memoryCache(new LruMemoryCache(2 * 1024 * 1024))

.memoryCacheSize(2 * 1024 * 1024)

.memoryCacheSizePercentage(13) // default

.diskCache(new UnlimitedDiscCache(cacheDir)) // default

.diskCacheSize(50 * 1024 * 1024)

.diskCacheFileCount(100)

.diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default

.imageDownloader(new BaseImageDownloader(context)) // default

// .imageDecoder(new BaseImageDecoder()) // default

.defaultDisplayImageOptions(DisplayImageOptions.createSimple())// default

.writeDebugLogs()

.build();

// Initialize ImageLoader with configuration.初始化配置

ImageLoader.getInstance().init(config);

}

 

}

<application

android:name=".base.MyApplication"

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

以上的配置大部分都有默认值,按照自己的需要进行配置,没必要全部都写上,现在的显示配置也是一样。

(四)显示配置

显示配置是具体到每个显示图片任务的配置

DisplayImageOptions options = new DisplayImageOptions.Builder()

.showImageOnLoading(R.drawable.ic_stub)// resource or drawable

.showImageForEmptyUri(R.drawable.ic_empty)// resource or drawable

.showImageOnFail(R.drawable.ic_error)// resource or drawable

.resetViewBeforeLoading(false) // default

.delayBeforeLoading(1000)

.cacheInMemory(false) // default

.cacheOnDisk(false) // default

.preProcessor(...)

.postProcessor(...)

.extraForDownloader(...)

.considerExifParams(false) // default

.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)// default

.bitmapConfig(Bitmap.Config.ARGB_8888)// default

.decodingOptions(...)

.displayer(new SimpleBitmapDisplayer()) // default

.handler(new Handler()) // default

.build();

(五)配置完了使用

用默认配置显示:ImageLoader.getInstance().displayImage(imageUrl, imageView);

用自定义配置显示:ImageLoader.getInstance().displayImage(imageUrl, imageViewoptions);

带监听事件的显示:

imageLoader.displayImage(imageUrl,imageView, options, new ImageLoadingListener() {

@Override

public void onLoadingStarted() {

//开始加载的时候执行

}

@Override

public void onLoadingFailed(FailReason failReason) {

//加载失败的时候执行

}

@Override

public void onLoadingComplete(Bitmap loadedImage) {

//加载成功的时候执行

}

@Override

public void onLoadingCancelled() {

//加载取消的时候执行

17.

}});

带监听事件和进度条的显示:

imageLoader.displayImage(imageUri,imageView, options, new ImageLoadingListener() {

@Override

public void onLoadingStarted(String imageUri, View view) {

...

}

@Override

public void onLoadingFailed(String imageUri, View view, FailReason failReason) {

...

}

@Override

public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

...

}

@Override

public void onLoadingCancelled(String imageUri, View view) {

...

}

}, new ImageLoadingProgressListener() {

@Override

public void onProgressUpdate(String imageUri, View view, int current, int total) {

...

}

});

有的文章提出加载本地图片也用ImageLoader.getInstance().displayImage,完全没有必要。

三、注意事项

1.上述提到的2个权限必须加入,否则会出错
2.ImageLoaderConfiguration必须配置并且全局化的初始化这个配置ImageLoader.getInstance().init(config);否则也会出现错误提示
3.ImageLoader是根据ImageViewheightwidth确定图片的宽高。
4.如果经常出现OOM
减少配置之中线程池的大小,(.threadPoolSize).推荐1-5
使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者try.imageScaleType(ImageScaleType.EXACTLY)
避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象;
使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();

对该类库源码的解析可以参考这篇大神的文章http://blog.csdn.net/xiaanming/article/details/39057201

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值