开发App过程当中,免不了要进行网络请求操做进行数据交换,好比下载图片,若是本身写一个下载图片的类进行操做的话,要考虑太多太多内容,必须线程池,内存溢出,图片磁盘缓存操做,图片内存缓存操做等等,至关麻烦。好在伟大的开源者们已经写好了一个比较完美的开源类库供你们使用Android-Universal-Image-Loader,这个类库已经被许多知名的软件所采用,当时我本身用这个开源类库的时候,百度了一大推,有查看了官方文档。如今把记录写下来供你们参考。android
Android-Universal-Image-Loader的目的是提供一个功能强大的,灵活的,高度可定制的图像加载,缓存和显示工具。它提供了大量的配置选项,并很好地控制图像加载和缓存。缓存
类库的特色网络
l 多线程的图像加载(同步或异步)多线程
l 灵活的图像加载配置选项(线程执行,下载,解码,内存和磁盘缓存,图像显示选项)app
l 自定义每一个显示图像的配置框架
l 在内存或磁盘上缓存(设备内存或SD卡)异步
l 监听加载进程(包括下载进度)ide
效果图工具
先来看下引入该类包后,加载图片的运行流程图post
从图中可看出,加载图片的时候一共分为三种状况:
(post process Bitmap一步,实际就是对该图片进行处理,好比加水印,加圆角等等,该框架没有给出具体实现,默认为null,若有须要本身能够实现,因此分析的时候能够忽略)
1. 图片在内存中缓存:直接显示图片。
2. 图片在磁盘中缓存:先解码,再暂时缓存到内存中,最后显示。
3. 图片没有缓存:先下载,再是否缓存到磁盘和内存,最后显示。
(一) Include Library
官网下载依赖jar包,导入工程中libs文件夹下并添加到工程路径便可。
(二) 加权限
<manifest> <!-- Include following permission if you load images from Internet --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Include following permission if you want to cache images on SD card --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ... </manifest>(三)全局配置
全局配置我通常写个类继承application,而后在Mainfest文件中声明
public class MyApplication extends Application { @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); initImageLoader(getApplicationContext()); } public static void initImageLoader(Context context){ 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, imageView,options);
带监听事件的显示:
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() { //加载取消的时候执行 }});带监听事件和进度条的显示:
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,彻底没有必要。
对该类库源码的解析能够参考这篇大神的文章http://blog.csdn.net/xiaanming/article/details/39057201