当前位置:   article > 正文

Android 图像异步加载之Android-Universal-Image-Loader_universalimageloader loadimagesync 缩放

universalimageloader loadimagesync 缩放

概述:

项目地址:https://github.com/nostra13/Android-Universal-Image-Loader
UIL(Universal-Image-Loader)异步图像加载、缓存和显示.这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影。
同类类库(Picasso),尽管Picasso拥有更好的API,但其缺乏自定义。而使用UIL构建器几乎可以配置所有(其中最重要的就是在抓取和缓存大型图片时,Picasso会失败)。
特点:
  • 多线程加载图像Multithread image loading (async or sync)
  • 宽泛的自定义配置Wide customization of ImageLoader's configuration (thread executors, downloader, decoder, memory and disk cache, display image options, etc.)
  • Many customization options for every display image call (stub images, caching switch, decoding options, Bitmap processing and displaying, etc.)
  • 图像缓存Image caching in memory and/or on disk (device's file system or SD card)
  • 加载过程监听Listening loading process (including downloading progress)
简单描述一下这个项目的结构:每一个图片的加载和显示任务都运行在独立的线程中,除非这个图片缓存在内存中,这种情况下图片会立即显示。如果需要的图片缓存在本地,他们会开启一个独立的线程队列。如果在缓存中没有正确的图片,任务线程会从线程池中获取,因此,快速显示缓存图片时不会有明显的障碍。


由于源码中不管是loadImageSync还是loadImage最后都会通过displayImage来加载。那我们看看其流程:

准备工作

安装:

maven:
  1. <dependency>
  2. <groupId>com.nostra13.universalimageloader</groupId>
  3. <artifactId>universal-image-loader</artifactId>
  4. <version>1.9.3</version>
  5. </dependency>
Gradle:
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'

添加网络和SD卡权限:

由于是使用过程中会图片获取要通过网络,并且有缓存设置,所以这2个权限必须要有。
  1. <uses-permission android:name="android.permission.INTERNET" />
  2. <!-- Include following permission if you want to cache images on SD card -->
  3. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

预配置Application or Activity class (before the first usage of ImageLoader)

  1. // Create global configuration and initialize ImageLoader with this config
  2. ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
  3. ...
  4. .build();
  5. ImageLoader.getInstance().init(config);

Acceptable URIs examples

"http://site.com/image.png" // from Web
"file:///mnt/sdcard/image.png" // from SD card
"file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)
"content://media/external/images/media/13" // from content provider
"content://media/external/video/media/13" // from content provider (video thumbnail)
"assets://image.png" // from assets
"drawable://" + R.drawable.img // from drawables (non-9patch images)
NOTE: Use drawable:// only if you really need it! Always consider the native way to load drawables - ImageView.setImageResource(...) instead of using of ImageLoader.

示例

  1. imageLoader.displayImage(imageUri, imageView);
  2. imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
  3. @Override
  4. public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
  5. // Do whatever you want with Bitmap
  6. }
  7. });
  8. // Load image, decode it to Bitmap and return Bitmap synchronously
  9. Bitmap bmp = imageLoader.loadImageSync(imageUri);
  10. // Load image, decode it to Bitmap and return Bitmap to callback
  11. ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
  12. imageLoader.loadImage(imageUri, targetSize, options, new SimpleImageLoadingListener() {
  13. @Override
  14. public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
  15. // Do whatever you want with Bitmap
  16. }
  17. });
  18. // Load image, decode it to Bitmap and return Bitmap synchronously
  19. ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
  20. Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options);
还可以通过 ImageLoadingProgressListener监听进度。

配置

ImageLoaderConfiguration应该是一个对于Application的全局对象,你应该只配置一次。
  1. // DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
  2. // See the sample project how to use ImageLoader correctly.
  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) //.推荐diskCacheExtraOptions(480, 800, null)
  7. .taskExecutor(...)
  8. .taskExecutorForCachedImages(...)
  9. .threadPoolSize(3) // default 推荐1-5
  10. .threadPriority(Thread.NORM_PRIORITY - 2) // default
  11. .tasksProcessingOrder(QueueProcessingType.FIFO) // default
  12. .denyCacheImageMultipleSizesInMemory() //设置内存缓存不允许缓存一张图片的多个尺寸,默认允许。
  13. .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //使用强引用的缓存使用它,不过推荐使用weak与strong引用结合的UsingFreqLimitedMemoryCache或者使用全弱引用的WeakMemoryCache
  14. .memoryCacheSize(2 * 1024 * 1024)
  15. .memoryCacheSizePercentage(13) // default
  16. .diskCache(new UnlimitedDiscCache(cacheDir)) // default
  17. .diskCacheSize(50 * 1024 * 1024)
  18. .diskCacheFileCount(100)
  19. .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
  20. .imageDownloader(new BaseImageDownloader(context)) // default
  21. .imageDecoder(new BaseImageDecoder()) // default
  22. .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
  23. .writeDebugLogs()
  24. .build();

示例配置缓存目录

File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache");  
.diskCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径  

配置Display Options

  1. // DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
  2. // See the sample project how to use ImageLoader correctly.
  3. DisplayImageOptions options = new DisplayImageOptions.Builder()
  4.         .showImageOnLoading(R.drawable.ic_stub) // resource or drawable
  5.         .showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable
  6.         .showImageOnFail(R.drawable.ic_error) // resource or drawable
  7.         .resetViewBeforeLoading(false)  // default
  8.         .delayBeforeLoading(1000)
  9.         .cacheInMemory(false) // default
  10.         .cacheOnDisk(false) // default
  11.         .preProcessor(...)
  12.         .postProcessor(...)
  13.         .extraForDownloader(...)
  14.         .considerExifParams(false) // default
  15.         .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 推荐.imageScaleType(ImageScaleType.EXACTLY) 节省内存
  16.         .bitmapConfig(Bitmap.Config.ARGB_8888) // default 推荐.bitmapConfig(Bitmap.Config.RGB_565)节省内存
  17.         .decodingOptions(...)
  18.         .displayer(new SimpleBitmapDisplayer()) // default 
  19. <span style="white-space:pre"> </span>/*推荐使用RoundedBitmapDisplayer (Displays bitmap with rounded corners)和
  20. <span style="white-space:pre"> </span>*FadeInBitmapDisplayer (Displays image with "fade in" animation
  21. <span style="white-space:pre"> </span>*但是使用RoundedBitmapDisplayer有些必要的注意事项,看后面提示。
  22. <span style="white-space:pre"> </span>*/
  23.         .handler(new Handler()) // default
  24.         .build();
以上配置中的:
1).imageScaleType(ImageScaleType imageScaleType) 是设置 图片的缩放方式
缩放类型mageScaleType:
EXACTLY :图像将完全按比例缩小的目标大小
EXACTLY_STRETCHED:图片会缩放到目标大小完全
IN_SAMPLE_INT:图像将被二次采样的整数倍
IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
NONE:图片不会调整
2).displayer(BitmapDisplayer displayer) 是设置 图片的显示方式
显示方式displayer:
RoundedBitmapDisplayer(int roundPixels) 设置圆角图片。
但是使用这个RoundedBitmapDisplayer必须注意几点
  • This implementation works only with ImageViews wrapped in ImageViewAware否则会出现异常ImageAware should wrap ImageView. ImageViewAware is expected.出现这种异常只能注释掉设置代码。
  • If this implementation doesn't meet your needs then consider RoundedImageView or CircularImageView projects for usage.
FakeBitmapDisplayer()这个类什么都没做
FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间
SimpleBitmapDisplayer()正常显示一张图片  

注意的问题

1、缓存默认情况下是没有启用的。可以通过配置DisplayImageOptions来启用。
  1. // Create default options which will be used for every
  2. // displayImage(...) call if no options will be passed to this method
  3. DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
  4. ...
  5. .cacheInMemory(true)
  6. .cacheOnDisk(true)<pre name="code" class="java">boolean pauseOnScroll = false; // or true
  7. boolean pauseOnFling = true; // or false
  8. PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling);
  9. listView.setOnScrollListener(listener);

... .build();ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()) ... .defaultDisplayImageOptions(defaultOptions) ... .build();ImageLoader.getInstance().init(config); // Do it on Application start
 
 
  1. // Then later, when you want to display image
  2. ImageLoader.getInstance().displayImage(imageUrl, imageView); // Default options will be used
或者通过如下方式:
  1. DisplayImageOptions options = new DisplayImageOptions.Builder()
  2. ...
  3. .cacheInMemory(true)
  4. .cacheOnDisk(true)
  5. ...
  6. .build();
  7. ImageLoader.getInstance().displayImage(imageUrl, imageView, options); // Incoming options will be used
2、为了防止list(listview,grid等)滚动迟钝,可以使用PauseOnScrollListener
  1. boolean pauseOnScroll = false; // or true
  2. boolean pauseOnFling = true; // or false
  3. PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling);
  4. listView.setOnScrollListener(listener);

几点注意事项

1. 上述提到的2个权限必须加入,否则会出错
2 .ImageLoaderConfiguration必须配置并且全局化的初始化这个配置ImageLoader.getInstance().init(config); 否则也会出现错误提示
3.ImageLoader是根据ImageView的height,width确定图片的宽高。
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();

延伸阅读-如何绘制圆角图片或者组件

1、可以参考: http://www.curious-creature.com/2012/12/11/android-recipe-1-image-with-rounded-corners/中的方法绘制图片圆角:
  1. To generate the rounded images I simply wrote a custom Drawable that draws a rounded rectangle using Canvas.drawRoundRect(). The trick is to use a Paint with a BitmapShader to fill the rounded rectangle with a texture instead of a simple color. Here is what the code looks like:
  2. BitmapShader shader;
  3. shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  4. Paint paint = new Paint();
  5. paint.setAntiAlias(true);
  6. paint.setShader(shader);
  7. RectF rect = new RectF(0.0f, 0.0f, width, height);
  8. // rect contains the bounds of the shape
  9. // radius is the radius in pixels of the rounded corners
  10. // paint contains the shader that will texture the shape
  11. canvas.drawRoundRect(rect, radius, radius, paint);
2、使用在线图片圆角绘制工具:http://www.asqql.com/gifyjtp/ 和http://www.roundpic.com/
3、使用UIL并继承ImageViewAware实现图片圆角ImageView
4、使用图片圆角开源库:https://github.com/vinc3m1/RoundedImageView;或者https://github.com/Pkmmte/CircularImageView


参考:
https://github.com/nostra13/Android-Universal-Image-Loader/wiki
http://blog.csdn.net/vipzjyno1/article/details/23206387
http://blog.csdn.net/kaiqiangzhang001/article/details/41721349
RoundedBitmapDisplayer类的APIDoc


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/105864?site
推荐阅读
相关标签
  

闽ICP备14008679号