ImageLoader简单使用
新建一个MyApplication继承Application,并在onCreate()中创建ImageLoader的配置参数,并初始化到ImageLoader中代码如下
1 package com.example.uil; 2 3 import com.nostra13.universalimageloader.core.ImageLoader; 4 import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; 5 6 import android.app.Application; 7 8 public class MyApplication extends Application { 9 10 @Override 11 public void onCreate() { 12 super.onCreate(); 13 14 //创建默认的ImageLoader配置参数 15 ImageLoaderConfiguration configuration = ImageLoaderConfiguration 16 .createDefault(this); 17 18 //Initialize ImageLoader with configuration. 19 ImageLoader.getInstance().init(configuration); 20 } 21 22 }
ImageLoaderConfiguration是图片加载器ImageLoader的配置参数,使用了建造者模式,这里是直接使用了 createDefault()方法创建一个默认的ImageLoaderConfiguration,当然我们还可以自己设置 ImageLoaderConfiguration,设置如下
1 //缓存文件夹 2 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); 3 File cacheDir = StorageUtils.getCacheDirectory(context); //缓存文件夹路径 4 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) 5 .memoryCacheExtraOptions(480, 800) // default = device screen dimensions 内存缓存文件的最大长宽 6 .diskCacheExtraOptions(480, 800, null) // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个 7 .taskExecutor(...) 8 .taskExecutorForCachedImages(...) 9 .threadPoolSize(3) // default 线程池内加载的数量 10 .threadPriority(Thread.NORM_PRIORITY - 2) // default 设置当前线程的优先级 11 .tasksProcessingOrder(QueueProcessingType.FIFO) // default 12 .denyCacheImageMultipleSizesInMemory() 13 .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现 14 .memoryCacheSize(2 * 1024 * 1024) // 内存缓存的最大值 15 .memoryCacheSizePercentage(13) // default 16 .diskCache(new UnlimitedDiscCache(cacheDir)) // default 可以自定义缓存路径 17 .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值 18 .diskCacheFileCount(100) // 可以缓存的文件数量 19 // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密 20 .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) 21 .imageDownloader(new BaseImageDownloader(context)) // default 22 .imageDecoder(new BaseImageDecoder()) // default 23 .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default 24 .writeDebugLogs() // 打印debug log 25 .build(); //开始构建
上面的这些就是所有的选项配置,我们在项目中不需要每一个都自己设置,一般使用createDefault()创建的 ImageLoaderConfiguration就能使用,然后调用ImageLoader的init()方法将 ImageLoaderConfiguration参数传递进去,ImageLoader使用单例模式。
1 <manifest> 2 <uses-permission android:name="android.permission.INTERNET" /> 3 <!-- Include next permission if you want to allow UIL to cache images on SD card --> 4 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 5 ... 6 <application android:name="MyApplication"> 7 ... 8 </application> 9 </manifest>
接下来我们就可以来加载图片了,首先我们定义好Activity的布局文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent"> 5 6 <ImageView 7 android:layout_gravity="center" 8 android:id="@+id/image" 9 android:src="@drawable/ic_empty" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" /> 12 13 </FrameLayout>
1 final ImageView mImageView = (ImageView) findViewById(R.id.image); 2 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 3 4 ImageLoader.getInstance().loadImage(imageUrl, new ImageLoadingListener() { 5 6 @Override 7 public void onLoadingStarted(String imageUri, View view) { 8 9 } 10 11 @Override 12 public void onLoadingFailed(String imageUri, View view, 13 FailReason failReason) { 14 15 } 16 17 @Override 18 public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 19 mImageView.setImageBitmap(loadedImage); 20 } 21 22 @Override 23 public void onLoadingCancelled(String imageUri, View view) { 24 25 } 26 }); 27 传入图片的url和ImageLoaderListener, 在回调方法onLoadingComplete()中将loadedImage设置到ImageView上面就行了,如果你觉得传入 ImageLoaderListener太复杂了,我们可以使用SimpleImageLoadingListener类,该类提供了 ImageLoaderListener接口方法的空实现,使用的是缺省适配器模式 28 final ImageView mImageView = (ImageView) findViewById(R.id.image); 29 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 30 31 ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener(){ 32 33 @Override 34 public void onLoadingComplete(String imageUri, View view, 35 Bitmap loadedImage) { 36 super.onLoadingComplete(imageUri, view, loadedImage); 37 mImageView.setImageBitmap(loadedImage); 38 } 39 40 });
如果我们要指定图片的大小该怎么办呢,这也好办,初始化一个ImageSize对象,指定图片的宽和高,代码如下
1 final ImageView mImageView = (ImageView) findViewById(R.id.image); 2 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 3 4 ImageSize mImageSize = new ImageSize(100, 100); 5 6 ImageLoader.getInstance().loadImage(imageUrl, mImageSize, new SimpleImageLoadingListener(){ 7 8 @Override 9 public void onLoadingComplete(String imageUri, View view, 10 Bitmap loadedImage) { 11 super.onLoadingComplete(imageUri, view, loadedImage); 12 mImageView.setImageBitmap(loadedImage); 13 } 14 15 });
上面只是很简单的使用ImageLoader来加载网络图片,在实际的开发中,我们并不会这么使用,那我们平常会怎么使用呢?我们会用到 DisplayImageOptions,他可以配置一些图片显示的选项,比如图片在加载中ImageView显示的图片,是否需要使用内存缓存,是否需 要使用文件缓存等等,可供我们选择的配置如下
1 DisplayImageOptions options = new DisplayImageOptions.Builder() 2 .showImageOnLoading(R.drawable.ic_stub) // 设置图片下载期间显示的图片 3 .showImageForEmptyUri(R.drawable.ic_empty) // 设置图片Uri为空或是错误的时候显示的图片 4 .showImageOnFail(R.drawable.ic_error) // 设置图片加载或解码过程中发生错误显示的图片 5 .resetViewBeforeLoading(false) // default 设置图片在加载前是否重置、复位 6 .delayBeforeLoading(1000) // 下载前的延迟时间 7 .cacheInMemory(false) // default 设置下载的图片是否缓存在内存中 8 .cacheOnDisk(false) // default 设置下载的图片是否缓存在SD卡中 9 .preProcessor(...) 10 .postProcessor(...) 11 .extraForDownloader(...) 12 .considerExifParams(false) // default 13 .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 设置图片以如何的编码方式显示 14 .bitmapConfig(Bitmap.Config.ARGB_8888) // default 设置图片的解码类型 15 .decodingOptions(...) // 图片的解码设置 16 .displayer(new SimpleBitmapDisplayer()) // default 还可以设置圆角图片new RoundedBitmapDisplayer(20) 17 .handler(new Handler()) // default 18 .build(); 19 // 20 .imageScaleType(ImageScaleType imageScaleType) //设置图片的缩放方式 21 缩放类型mageScaleType: 22 EXACTLY :图像将完全按比例缩小的目标大小 23 EXACTLY_STRETCHED:图片会缩放到目标大小完全 24 IN_SAMPLE_INT:图像将被二次采样的整数倍 25 IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小 26 NONE:图片不会调整 27 2).displayer(BitmapDisplayer displayer) //设置图片的显示方式 28 显示方式displayer: 29 RoundedBitmapDisplayer(int roundPixels)设置圆角图片 30 FakeBitmapDisplayer()这个类什么都没做 31 FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间 32 SimpleBitmapDisplayer()正常显示一张图片 33 //参数补充 34 .considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转) 35 .displayer(new FadeInBitmapDisplayer(100))// 图片加载好后渐入的动画时间 36 我们将上面的代码稍微修改下 37 final ImageView mImageView = (ImageView) findViewById(R.id.image); 38 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 39 ImageSize mImageSize = new ImageSize(100, 100); 40 41 //显示图片的配置 42 DisplayImageOptions options = new DisplayImageOptions.Builder() 43 .cacheInMemory(true) 44 .cacheOnDisk(true) 45 .bitmapConfig(Bitmap.Config.RGB_565) 46 .build(); 47 48 ImageLoader.getInstance().loadImage(imageUrl, mImageSize, options, new SimpleImageLoadingListener(){ 49 50 @Override 51 public void onLoadingComplete(String imageUri, View view, 52 Bitmap loadedImage) { 53 super.onLoadingComplete(imageUri, view, loadedImage); 54 mImageView.setImageBitmap(loadedImage); 55 } 56 57 });
1 final ImageView mImageView = (ImageView) findViewById(R.id.image); 2 String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; 3 4 //显示图片的配置 5 DisplayImageOptions options = new DisplayImageOptions.Builder() 6 .showImageOnLoading(R.drawable.ic_stub) 7 .showImageOnFail(R.drawable.ic_error) 8 .cacheInMemory(true) 9 .cacheOnDisk(true) 10 .bitmapConfig(Bitmap.Config.RGB_565) 11 .build(); 12 13 ImageLoader.getInstance().displayImage(imageUrl, mImageView, options);
从上面的代码中,我们可以看出,使用displayImage()比使用loadImage()方便很多,也不需要添加 ImageLoadingListener接口,我们也不需要手动设置ImageView显示Bitmap对象,直接将ImageView作为参数传递到 displayImage()中就行了,图片显示的配置选项中,我们添加了一个图片加载中ImageVIew上面显示的图片,以及图片加载出现错误显示的 图片,效果如下,刚开始显示ic_stub图片,如果图片加载成功显示图片,加载产生错误显示ic_error
这个方法使用起来比较方便,而且使用displayImage()方法 他会根据控件的大小和imageScaleType来自动裁剪图片,我们修改下MyApplication,开启Log打印
1 public class MyApplication extends Application { 2 3 @Override 4 public void onCreate() { 5 super.onCreate(); 6 7 //创建默认的ImageLoader配置参数 8 ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this) 9 .writeDebugLogs() //打印log信息 10 .build(); 11 12 13 //Initialize ImageLoader with configuration. 14 ImageLoader.getInstance().init(configuration); 15 } 16 17 }
我们来看下图片加载的Log信息
第一条信息中,告诉我们开始加载图片,打印出图片的url以及图片的最大宽度和高度,图片的宽高默认是设备的宽高,当然如果我们很清楚图片的大小, 我们也可以去设置这个大小,在ImageLoaderConfiguration的选项中memoryCacheExtraOptions(int maxImageWidthForMemoryCache, int maxImageHeightForMemoryCache)
第二条信息显示我们加载的图片来源于网络
第三条信息显示图片的原始大小为1024 x 682 经过裁剪变成了512 x 341
第四条显示图片加入到了内存缓存中,我这里没有加入到sd卡中,所以没有加入文件缓存的Log
1 imageLoader.displayImage(imageUrl, mImageView, options, new SimpleImageLoadingListener(), new ImageLoadingProgressListener() { 2 3 @Override 4 public void onProgressUpdate(String imageUri, View view, int current, 5 int total) { 6 7 } 8 });
1 //显示图片的配置 2 DisplayImageOptions options = new DisplayImageOptions.Builder() 3 .showImageOnLoading(R.drawable.ic_stub) 4 .showImageOnFail(R.drawable.ic_error) 5 .cacheInMemory(true) 6 .cacheOnDisk(true) 7 .bitmapConfig(Bitmap.Config.RGB_565) 8 .build(); 9 10 final ImageView mImageView = (ImageView) findViewById(R.id.image); 11 String imagePath = "/mnt/sdcard/image.png"; 12 String imageUrl = Scheme.FILE.wrap(imagePath); 13 14 // String imageUrl = "//img-my.csdn.net/uploads/201309/01/1378037235_7476.jpg"; 15 16 imageLoader.displayImage(imageUrl, mImageView, options);
当然还有来源于Content provider,drawable,assets中,使用的时候也很简单,我们只需要给每个图片来源的地方加上Scheme包裹起来(Content provider除外),然后当做图片的url传递到imageLoader中,Universal-Image-Loader框架会根据不同的 Scheme获取到输入流
1 //图片来源于Content provider 2 String contentprividerUrl = "content://media/external/audio/albumart/13"; 3 4 //图片来源于assets 5 String assetsUrl = Scheme.ASSETS.wrap("image.png"); 6 7 //图片来源于 8 String drawableUrl = Scheme.DRAWABLE.wrap("R.drawable.image");
1 listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling)); 2 gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
- 减少线程池中线程的个数,在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推荐配置1-5
- 在DisplayImageOptions选项中配置bitmapConfig为Bitmap.Config.RGB_565,因为默认是ARGB_8888, 使用RGB_565会比使用ARGB_8888少消耗2倍的内存
- 在ImageLoaderConfiguration中配置图片的内存缓存为memoryCache(new WeakMemoryCache()) 或者不使用内存缓存
- 在DisplayImageOptions选项中设置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScaleType.EXACTLY)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步