您的位置:首页 > 理论基础 > 计算机网络

Android_开源框架_AndroidUniversalImageLoader网络图片加载

2015-04-11 17:21 447 查看


1.功能概要

Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。
(1).使用多线程加载图片

(2).灵活配置ImageLoader的基本参数,包括线程数、缓存方式、图片显示选项等;

(3).图片异步加载缓存机制,包括内存缓存及SDCard缓存;

(4).采用监听器监听图片加载过程及相应事件的处理;

(5).配置加载的图片显示选项,比如图片的圆角处理及渐变动画。


2.简单实现

ImageLoader采用单例设计模式,ImageLoader imageLoader = ImageLoader.getInstance();得到该对象,每个ImageLoader采用单例设计模式,ImageLoader必须调用init()方法完成初始化。

// 1.完成ImageLoaderConfiguration的配置

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)

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

.discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)

.taskExecutor(...)

.taskExecutorForCachedImages(...)

.threadPoolSize(3) // default

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

.tasksProcessingOrder(QueueProcessingType.FIFO) // default

.denyCacheImageMultipleSizesInMemory()

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

.memoryCacheSize(2 * 1024 * 1024)

.memoryCacheSizePercentage(13) // default

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

.discCacheSize(50 * 1024 * 1024) // 缓冲大小

.discCacheFileCount(100) // 缓冲文件数目

.discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default

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

.imageDecoder(new BaseImageDecoder()) // default

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

.writeDebugLogs()

.build();



// 2.单例ImageLoader类的初始化

ImageLoader imageLoader = ImageLoader.getInstance();

imageLoader.init(config); //这句话很重要



// 3.DisplayImageOptions实例对象的配置

// 以下的设置再调用displayImage()有效,使用loadImage()无效

DisplayImageOptions options = new DisplayImageOptions.Builder()

.showStubImage(R.drawable.ic_stub) // image在加载过程中,显示的图片

.showImageForEmptyUri(R.drawable.ic_empty) // empty URI时显示的图片

.showImageOnFail(R.drawable.ic_error) // 不是图片文件 显示图片

.resetViewBeforeLoading(false) // default

.delayBeforeLoading(1000)

.cacheInMemory(false) // default 不缓存至内存

.cacheOnDisc(false) // default 不缓存至手机SDCard

.preProcessor(...)

.postProcessor(...)

.extraForDownloader(...)

.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)// default

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

.decodingOptions(...)

.displayer(new SimpleBitmapDisplayer()) // default 可以设置动画,比如圆角或者渐变

.handler(new Handler()) // default

.build();



// 4图片加载

// 4.1 调用displayImage

imageLoader.displayImage(

uri, /*

String imageUri = "http://site.com/image.png"; // from Web

String imageUri = "file:///mnt/sdcard/image.png"; // from SD card

String imageUri = "content://media/external/audio/albumart/13"; // from content provider

String imageUri = "assets://image.png"; // from assets

*/

imageView, // 对应的imageView控件

options); // 与之对应的image显示方式选项



// 4.2 调用loadImage

// 对于部分DisplayImageOptions对象的设置不起作用

imageLoader.loadImage(

uri,

options,

new MyImageListener()); //ImageLoadingListener

class MyImageListener extends SimpleImageLoadingListener{



@Override

public void onLoadingStarted(String imageUri, View view) {

imageView.setImageResource(R.drawable.loading);

super.onLoadingStarted(imageUri, view);

}



@Override

public void onLoadingFailed(String imageUri, View view,

FailReason failReason) {

imageView.setImageResource(R.drawable.no_pic);

super.onLoadingFailed(imageUri, view, failReason);

}



@Override

public void onLoadingComplete(String imageUri, View view,

Bitmap loadedImage) {

imageView.setImageBitmap(loadedImage);

super.onLoadingComplete(imageUri, view, loadedImage);

}



@Override

public void onLoadingCancelled(String imageUri, View view) {

imageView.setImageResource(R.drawable.cancel);

super.onLoadingCancelled(imageUri, view);

}



}


3.支持的Uri

String imageUri = "http://site.com/image.png"; // from Web

String imageUri = "file:///mnt/sdcard/image.png"; // from SD card

String imageUri = "content://media/external/audio/albumart/13"; // from content provider

String imageUri = "assets://image.png"; // from assets

String imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)

加载drawables下图片,可以通过ImageView.setImageResource(...) 而不是通过上面的ImageLoader.


4.缓冲至手机

默认不能保存缓存,必须通过下面的方式指定

DisplayImageOptions options = new DisplayImageOptions.Builder()

...

.cacheInMemory(true)

.cacheOnDisc(true)

...

.build();

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())

...

.defaultDisplayImageOptions(options)

...

.build();

ImageLoader.getInstance().init(config); // Do it on Application start



ImageLoader.getInstance().displayImage(imageUrl, imageView); /*

默认为defaultDisplayImageOptions设定的options对象,此处不用指定options对象 */

或者通过下面这种方式

DisplayImageOptions options = new DisplayImageOptions.Builder()

...

.cacheInMemory(true)

.cacheOnDisc(true)

...

.build();

ImageLoader.getInstance().displayImage(imageUrl, imageView, options); //此处指定options对象

由于缓存需要在外设中写入数据,故需要添加下面的权限

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


5.OutOfMemoryError

如果OutOfMemoryError错误很常见,可以通过下面的方式设置

(1).减少configuration中线程池的线程数目(.threadPoolSize(...)) 推荐为1 - 5

(2).display options通过.bitmapConfig(Bitmap.Config.RGB_565)设置. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.

(3).使用configuration的memoryCache(new WeakMemoryCache())方法 或者不调用.cacheInMemory()方法

(4).display options通过.imageScaleType(ImageScaleType.IN_SAMPLE_INT) 或者 .imageScaleType(ImageScaleType.EXACTLY)方法

(4).避免使用RoundedBitmapDisplayer,它创建了一个新的ARGB_8888 Bitmap对象


6.内存缓存管理

通过imageLoaderConfiguration.memoryCache([new LruMemoryCache(1)]))对手机内存缓存进行管理
LruMemoryCache
API >= 9默认.it is moved to the head of a queue.
FreqLimitedMemoryCache
当超过缓存大小后,删除最近频繁使用的bitmap
LRULimitedMemoryCache
API < 9 默认.当超过缓存大小后,删除最近使用的bitmap
FIFOLimitedMemoryCache
FIFO rule is used for deletion when cache size limit is exceeded
LargestLimitedMemoryCache
The largest bitmap is deleted when cache size limit is exceeded
WeakMemoryCache
Unlimited cache


7.SDcard缓存管理

通过imageLoaderConfiguration.discCache([new TotalSizeLimitedDiscCache()]))对SD卡缓存进行管理
UnlimitedDiscCache
default The fastest cache, doesn't limit cache size
TotalSizeLimitedDiscCache
Cache limited by total cache size. If cache size exceeds specified limit then file with themost oldest lastusage date will be deleted
FileCountLimitedDiscCache
Cache limited by file count. If file count in cache directory exceeds specified limit then file with the most oldest last usage date will be deleted.
LimitedAgeDiscCache
Size-unlimited cache with limited files' lifetime. If age of cached file exceeds defined limit then it will be deleted from cache.
UnlimitedDiscCache is 30%-faster than other limited disc cache implementations.

前因后果不废话了,直接总结了:

UniversalImageloader请求加载的图片,在动态高度情况下会有模糊情况发生。经自己测试和网上翻阅资料,解决方式有三:

1. 若设置了默认高度(非WRAP_CONTENT、MATCH_PARENT),想在图片加载后动态高度,在请求图片前能提前知道图片高度的情况下(看api设计),可以在调用displayImage前先调整imageView的LayoutParams.height。因为Imageloader在请求到图片后,会参考imageView宽高(道听途说,没看代码)

2. 在调用的displayImage方法中增加回调ImageLoadingListener,在加载完成后调整imageView高度

Java代码


ImageLoader.getInstance().displayImage(imgUrl, imageView, App.options, new ImageLoadingListener() {

@Override

public void onLoadingStarted(String arg0, View arg1) {}

@Override

public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {}



@Override

public void onLoadingComplete(String arg0, View arg1, Bitmap bitmap) {

LayoutParams params = productImage.getLayoutParams();

params.height = (int)(ScreenUtils.WIDTH / bitmap.getWidth() * bitmap.getHeight());

}



@Override

public void onLoadingCancelled(String arg0, View arg1) {}

});

3. 框架作者给的解决方法,通过imageView.post()去调用displayImage

Java代码


imageView.post(new Runnable(){

@Override

public void run(){

ImageLoader.getInstance().displayImage(imgUrl, imageView, App.options);

}

});



具体用哪种,看个人喜好吧。



如果通过以上任意一种方式后,图片看上去比原图还是模糊,别乱找了,肯定options设置问题。

Java代码


options = new DisplayImageOptions.Builder()

...

.cacheInMemory(true) //设置下载的图片是否缓存在内存中

.cacheOnDisk(true) //设置下载的图片是否缓存在SD卡中

.considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转)

.imageScaleType(ImageScaleType.EXACTLY)//设置图片以如何的编码方式显示

<span style="background-color: #ffffff; color: #ff0000;">.bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型//</span>

...

如果你也是网上扒来的例子,十有八九是上边这样,问题就出在红色字体那行设置图片解码器上,查查资料就会发现,RGB_565是把图像压缩了的,如果你的图片本身有渐变色,用这个解码器解出来的图片看上会有尿布晾干那种痕迹;不过图片质量高的情况下问题不大。我们看下解释:

ALPHA_8 代表8位Alpha位图

ARGB_4444 代表16位ARGB位图,由4个4位组成

ARGB_8888 代表32位ARGB位图,由4个8位组成

RGB_565 代表16位RGB位图,R为5位,G为6位,B为5位】

转载自:http://vase.iteye.com/blog/2169517(解决图片模糊不清)
http://www.cnblogs.com/wanqieddy/p/3836485.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐