Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。
(1).使用多线程加载图片
(2).灵活配置ImageLoader的基本参数,包括线程数、缓存方式、图片显示选项等;
(3).图片异步加载缓存机制,包括内存缓存及SDCard缓存;
(4).采用监听器监听图片加载过程及相应事件的处理;
(5).配置加载的图片显示选项,比如图片的圆角处理及渐变动画。
常用的功能,网上都有了,现在讲一下,加载后手工
(1)圆角化等处理
/** * 加载图片 * * @param uri * @param imageView * @param options * @param spinner 进度条,可以要可以不要 * @param imageLoadingListener 图片加载监听器 * @param needRoundImage 图片是否圆角化 * */ public void display(String uri , ImageView imageView , DisplayImageOptions options , final ProgressBar spinner , ImageLoadingListener imageLoadingListener , final boolean needRoundImage){ try { if(options == null){ options = new DisplayImageOptions.Builder() // .showStubImage(R.drawable.default_photo_small) // .showImageForEmptyUri(R.drawable.default_photo_small) // .showImageOnFail(R.drawable.default_photo_small) .resetViewBeforeLoading(true) .cacheOnDisc(true) .imageScaleType(ImageScaleType.EXACTLY) // .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) .bitmapConfig(Bitmap.Config.RGB_565) // .displayer(new FadeInBitmapDisplayer(300)) .build(); } if(imageLoadingListener == null){ imageLoadingListener = new SimpleImageLoadingListener() { @Override public void onLoadingStarted(String imageUri, View view) { if(spinner != null){ spinner.setVisibility(View.VISIBLE); } } @Override public void onLoadingFailed(String imageUri, View view, FailReason failReason) { String message = null; switch (failReason.getType()) { case IO_ERROR: message = "Input/Output error"; break; case DECODING_ERROR: message = "Image can't be decoded"; break; case NETWORK_DENIED: message = "Downloads are denied"; break; case OUT_OF_MEMORY: message = "Out Of Memory error"; break; case UNKNOWN: message = "Unknown error"; break; } CLog.e(TAG, imageUri+"/t加载失败!"); if(spinner != null){ spinner.setVisibility(View.GONE); } } @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { /** * 圆角化处理 */ if(needRoundImage){ ((ImageView) view).setImageBitmap(toRoundBitmap(loadedImage)); } if(spinner != null){ CLog.d(TAG, imageUri+"/t加载成功!" ); spinner.setVisibility(View.GONE); } } }; } imageLoader.displayImage(uri, imageView , options , imageLoadingListener); } catch (Exception e) { CLog.e(TAG , "exception!" , e); } } /** * 转换图片成圆形 * @param bitmap * 传入Bitmap对象 * @return */ public Bitmap toRoundBitmap(Bitmap bitmap) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); float roundPx; float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom; if (width <= height) { roundPx = width / 2; left = 0; top = 0; right = width; bottom = width; height = width; dst_left = 0; dst_top = 0; dst_right = width; dst_bottom = width; } else { roundPx = height / 2; float clip = (width - height) / 2; left = clip; right = width - clip; top = 0; bottom = height; width = height; dst_left = 0; dst_top = 0; dst_right = height; dst_bottom = height; } Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom); final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom); final RectF rectF = new RectF(dst); paint.setAntiAlias(true);// 设置画笔无锯齿 canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas paint.setColor(color); // 以下有两种方法画圆,drawRounRect和drawCircle // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);// 画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。 canvas.drawCircle(roundPx, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));// 设置两张图片相交时的模式,参考http://trylovecatch.iteye.com/blog/1189452 canvas.drawBitmap(bitmap, src, dst, paint); //以Mode.SRC_IN模式合并bitmap和已经draw了的Circle return output; }
(2)手工从缓存中取出bitmap
/** * 使用此加载框架的imageloader加载的图片,设置了缓存后,下次使用,手工从缓存取出来用,这时特别要注意,不能直接使用: * imageLoader.getMemoryCache().get(uri)来获取,因为在加载过程中,key是经过运算的,而不单单是uri,而是: * String memoryCacheKey = MemoryCacheUtil.generateKey(uri, targetSize); * * @return */ public Bitmap getBitmapFromCache(String uri){//这里的uri一般就是图片网址 List<String> memCacheKeyNameList = MemoryCacheUtil.findCacheKeysForImageUri(uri , imageLoader.getMemoryCache()); if(memCacheKeyNameList != null && memCacheKeyNameList.size() > 0){ CLog.d(TAG , "memCache size ============> " + memCacheKeyNameList.size()); for(String each:memCacheKeyNameList){ CLog.d(TAG , "memCache each ============> " + each); } return imageLoader.getMemoryCache().get(memCacheKeyNameList.get(0)); } return null; }
取出的key有可能有两个,如:
http://tizi-zujuan-thumb.oss.aliyuncs.com/qfactory_word_img/201405/ae/309e9b359d0541f87e40f0d8eCKS74F.gif
http://tizi-zujuan-thumb.oss.aliyuncs.com/qfactory_word_img/201405/ae/309e9b359d0541f87e40f0d8eCKS74F.gif_720x1280
(3)加载图片(没有imageview控件,只想加载图片的bitmap到内存中)
/** * 加载图片 * @param uri * @param listener */ public void loadImage(String uri , ImageLoadingListener listener){ // imageLoader.loadImage(uri, listener); options = new DisplayImageOptions.Builder() .showStubImage(R.drawable.default_photo_small) .showImageForEmptyUri(R.drawable.default_photo_small) .showImageOnFail(R.drawable.default_photo_small) // .resetViewBeforeLoading(true) .cacheOnDisc(true) .cacheInMemory(true) .imageScaleType(ImageScaleType.EXACTLY) // .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // .bitmapConfig(Bitmap.Config.RGB_565) // .displayer(new FadeInBitmapDisplayer(300)) .resetViewBeforeLoading(true) .build(); imageLoader.loadImage(uri, options, listener); }
加载使用示例:
/** * 网络加载图片 * 这里需要注意的是,一个问题界面,会有多张如公式等小图,他们在加载过程中,都会到方法onLoadingStarted,但如果图多同时加载,后面几张图就可以加载不出来, * 会进入onLoadingCancelled方法,所以这里在onLoadingCancelled方法里再调用typesetDelegate.refresh();方法刷新一下图, * 图应该是下载下来了,只是不知道为什么到了onLoadingCancelled方法。 */ UniversalImageLoaderUtil.getInstance().loadImage(getBitmapUrl().trim(), new ImageLoadingListener() { @Override public void onLoadingStarted(String imageUri, View view) { CLog.d(TAG , "onLoadingStarted ===>" + imageUri); } @Override public void onLoadingFailed(String imageUri, View view, FailReason failReason) { CLog.e(TAG , "onLoadingFailed ===>" + imageUri); } @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { if(null == loadedImage){ return; } boolean bool = (Math.abs(loadedImage.getWidth() - TiKuBitmapSpan.this.getPresetWidth()) > TYPESET_THRESHOLD) || (Math.abs(loadedImage.getHeight() - TiKuBitmapSpan.this.getPresetHeight()) > TYPESET_THRESHOLD); /** * 调用refresh方法,刷新控件界面,那么又会重走该render方法,这里图片已在缓存,所以就不会再去网络加载,不会再走回这里造成死循环,一直刷新 */ typesetDelegate.refresh(bool); CLog.d(TAG , "onLoadingComplete bool===>" + bool); } @Override public void onLoadingCancelled(String imageUri, View view) { /** * 调用refresh方法,刷新控件界面,那么又会重走该render方法,这里图片已在缓存,所以就不会再去网络加载,不会再走回这里造成死循环,一直刷新 */ typesetDelegate.refresh(true); CLog.e(TAG , "onLoadingCancelled ===>" + imageUri); } });
这里特别要注意的是,同时加载多个url的bitmap,有可能会因超时等原因(具体我也不知道什么的原因),最后跳到监听器的onLoadingCancelled方法(此时图片也可能在后台加载了),所以对种特殊情况也要处理。
完整的工具类代码:
package com.yiduoyun.tiku.util; import java.util.List; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator; import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.FailReason; import com.nostra13.universalimageloader.core.assist.ImageLoadingListener; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.assist.MemoryCacheUtil; import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import com.yiduoyun.tiku.R; /** * 使用开源图片加载框架Universal-Image-Loader * * @author chenwenbiao * @date 2013-11-1 上午11:21:45 * @version V1.0 */ public class UniversalImageLoaderUtil { private static String TAG = UniversalImageLoaderUtil.class.getName(); private static UniversalImageLoaderUtil universalImageLoaderUtil = null; private static ImageLoader imageLoader = null; private static DisplayImageOptions options = null; // private static ProgressBar spinner = null; /** * 返回图片加载工具类实例 * @return */ public static UniversalImageLoaderUtil getInstance() { if (universalImageLoaderUtil == null) { synchronized (UniversalImageLoaderUtil.class) { if (universalImageLoaderUtil == null) { universalImageLoaderUtil = new UniversalImageLoaderUtil(); } } } return universalImageLoaderUtil; } /** * 记得使用前初始化context * @param aContext */ public void setContext(Context aContext) { imageLoader = ImageLoader.getInstance(); // imageLoader.init(ImageLoaderConfiguration.createDefault(aContext)); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(aContext.getApplicationContext()) .memoryCache(new LruMemoryCache(16 * 1024 * 1024)) // .memoryCacheSize(16 * 1024 * 1024) .discCacheSize(100 * 1024 * 1024) .denyCacheImageMultipleSizesInMemory() .discCacheFileNameGenerator(new Md5FileNameGenerator()) .tasksProcessingOrder(QueueProcessingType.LIFO) // .discCacheFileCount(100) // .writeDebugLogs() .threadPoolSize(10) .build(); /*File cacheDir = StorageUtils.getCacheDirectory(aContext); CLog.d(TAG , "cache direction =======> " + cacheDir); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(aContext) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) // .taskExecutor(null) // .taskExecutorForCachedImages(null) .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(aContext)) // default // .imageDecoder(new BaseImageDecoder(true)) // default .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default .writeDebugLogs() .build();*/ /*File cacheDir = StorageUtils.getCacheDirectory(aContext); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(aContext) //如果图片尺寸大于了这个参数,那么就会这按照这个参数对图片大小进行限制并缓存 .memoryCacheExtraOptions(480, 800) // default=device screen dimensions .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75 , null) // .memoryCacheExtraOptions(40, 80) // default=device screen dimensions // .discCacheExtraOptions(40, 80, CompressFormat.JPEG, 75 , null) // .taskExecutor(AsyncTask.THREAD_POOL_EXECUTOR) // .taskExecutorForCachedImages(AsyncTask.THREAD_POOL_EXECUTOR) .threadPoolSize(3) // default .threadPriority(Thread.NORM_PRIORITY - 1) // default .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) .memoryCacheSize(2 * 1024 * 1024) .discCache(new UnlimitedDiscCache(cacheDir)) // default .discCacheSize(50 * 1024 * 1024) .discCacheFileCount(100) .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default .imageDownloader(new BaseImageDownloader(aContext)) // default .imageDecoder(new BaseImageDecoder(false)) // default .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default // .enableLogging() .build(); */ try { imageLoader.init(config); } catch (Exception e) { CLog.e(TAG , "exception" , e); } } /** * 获取图片加载器实例 * @return */ public static ImageLoader getImageLoader(){ return imageLoader; } /** * 加载图片 * * @param uri * @param imageView * @param options * @param spinner 进度条,可以要可以不要 * @param imageLoadingListener 图片加载监听器 * @param needRoundImage 图片是否圆角化 * */ public void display(String uri , ImageView imageView , DisplayImageOptions options , final ProgressBar spinner , ImageLoadingListener imageLoadingListener , final boolean needRoundImage){ try { if(options == null){ options = new DisplayImageOptions.Builder() // .showStubImage(R.drawable.default_photo_small) // .showImageForEmptyUri(R.drawable.default_photo_small) // .showImageOnFail(R.drawable.default_photo_small) .resetViewBeforeLoading(true) .cacheOnDisc(true) .imageScaleType(ImageScaleType.EXACTLY) // .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) .bitmapConfig(Bitmap.Config.RGB_565) // .displayer(new FadeInBitmapDisplayer(300)) .build(); } if(imageLoadingListener == null){ imageLoadingListener = new SimpleImageLoadingListener() { @Override public void onLoadingStarted(String imageUri, View view) { if(spinner != null){ spinner.setVisibility(View.VISIBLE); } } @Override public void onLoadingFailed(String imageUri, View view, FailReason failReason) { String message = null; switch (failReason.getType()) { case IO_ERROR: message = "Input/Output error"; break; case DECODING_ERROR: message = "Image can't be decoded"; break; case NETWORK_DENIED: message = "Downloads are denied"; break; case OUT_OF_MEMORY: message = "Out Of Memory error"; break; case UNKNOWN: message = "Unknown error"; break; } CLog.e(TAG, imageUri+"/t加载失败!"); if(spinner != null){ spinner.setVisibility(View.GONE); } } @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { /** * 圆角化处理 */ if(needRoundImage){ ((ImageView) view).setImageBitmap(toRoundBitmap(loadedImage)); } if(spinner != null){ CLog.d(TAG, imageUri+"/t加载成功!" ); spinner.setVisibility(View.GONE); } } }; } imageLoader.displayImage(uri, imageView , options , imageLoadingListener); } catch (Exception e) { CLog.e(TAG , "exception!" , e); } } public void display(String uri , ImageView imageView , DisplayImageOptions options , final ProgressBar spinner , final boolean needRoundImage){ display(uri, imageView, options, spinner, null , needRoundImage); } /** * 加载图片,并将图片圆角化 * * @param uri * @param imageView * @param roundPixels */ public void display(String uri , ImageView imageView , int roundPixels){ try { if(roundPixels < 1){ roundPixels = 10000;//搞个巨大的数据,让它变圆 } options = new DisplayImageOptions.Builder() .showStubImage(R.drawable.default_photo_big) .showImageForEmptyUri(R.drawable.default_photo_big) .showImageOnFail(R.drawable.default_photo_big) .resetViewBeforeLoading(true) .cacheOnDisc(true) .imageScaleType(ImageScaleType.IN_SAMPLE_INT) .displayer(new RoundedBitmapDisplayer(roundPixels)) .bitmapConfig(Bitmap.Config.RGB_565) .displayer(new FadeInBitmapDisplayer(300)) .build(); imageLoader.displayImage(uri, imageView, options, new SimpleImageLoadingListener() { @Override public void onLoadingFailed(String imageUri, View view, FailReason failReason) { String message = null; switch (failReason.getType()) { case IO_ERROR: message = "Input/Output error"; break; case DECODING_ERROR: message = "Image can't be decoded"; break; case NETWORK_DENIED: message = "Downloads are denied"; break; case OUT_OF_MEMORY: message = "Out Of Memory error"; break; case UNKNOWN: message = "Unknown error"; break; } CLog.e(TAG, "load image error! message:" + message); } }); } catch (Exception e) { CLog.e(TAG , "exception!" , e); } } /** * 转换图片成圆形 * @param bitmap * 传入Bitmap对象 * @return */ public Bitmap toRoundBitmap(Bitmap bitmap) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); float roundPx; float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom; if (width <= height) { roundPx = width / 2; left = 0; top = 0; right = width; bottom = width; height = width; dst_left = 0; dst_top = 0; dst_right = width; dst_bottom = width; } else { roundPx = height / 2; float clip = (width - height) / 2; left = clip; right = width - clip; top = 0; bottom = height; width = height; dst_left = 0; dst_top = 0; dst_right = height; dst_bottom = height; } Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom); final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom); final RectF rectF = new RectF(dst); paint.setAntiAlias(true);// 设置画笔无锯齿 canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas paint.setColor(color); // 以下有两种方法画圆,drawRounRect和drawCircle // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);// 画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。 canvas.drawCircle(roundPx, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));// 设置两张图片相交时的模式,参考http://trylovecatch.iteye.com/blog/1189452 canvas.drawBitmap(bitmap, src, dst, paint); //以Mode.SRC_IN模式合并bitmap和已经draw了的Circle return output; } /** * 使用此加载框架的imageloader加载的图片,设置了缓存后,下次使用,手工从缓存取出来用,这时特别要注意,不能直接使用: * imageLoader.getMemoryCache().get(uri)来获取,因为在加载过程中,key是经过运算的,而不单单是uri,而是: * String memoryCacheKey = MemoryCacheUtil.generateKey(uri, targetSize); * * @return */ public Bitmap getBitmapFromCache(String uri){//这里的uri一般就是图片网址 List<String> memCacheKeyNameList = MemoryCacheUtil.findCacheKeysForImageUri(uri , imageLoader.getMemoryCache()); if(memCacheKeyNameList != null && memCacheKeyNameList.size() > 0){ CLog.d(TAG , "memCache size ============> " + memCacheKeyNameList.size()); for(String each:memCacheKeyNameList){ CLog.d(TAG , "memCache each ============> " + each); } return imageLoader.getMemoryCache().get(memCacheKeyNameList.get(0)); } return null; } /** * @Title: getLocalBitmapFromCache * @Description: 这个方法只适用于加载本地图片的情况(考虑到计算key的过程),这里的key使用的是文本,注意添加内存缓存和获取Bitmap缓存的key一定要一致 * @author gaoshunsheng * @param @param uri * @return Bitmap * @throws */ // public Bitmap getLocalBitmapFromCache(String text) // { // return imageLoader.getMemoryCache().get(text); // } // // /** // * @Title: addBitmap2Memorycache // * @Description: 添加Bitmap对象到缓存中,这里一般用于本地资源图片,key为文本 // * @author gaoshunsheng // * @param @param text // * @param @param value // * @return void // * @throws // */ // public void addBitmap2Memorycache(String text, Bitmap value) // { // imageLoader.getMemoryCache().put(text, value); // } // // /** // * @Title: loadImageAsync // * @Description: 异步加载图片,不显示在某个View上 // * @author gaoshunsheng // * @param @param uri // * @param @param listener // * @return void // * @throws // */ // public void loadImageAsync(String uri, ImageLoadingListener listener) // { // imageLoader.loadImage(uri, listener); // } /** * 清除缓存 */ public void clearCache(){ if(imageLoader != null){ try { imageLoader.clearMemoryCache(); imageLoader.clearDiscCache(); } catch (Exception e) { CLog.e(TAG , "exception" , e); } } } /** * 加载图片 * @param uri * @param listener */ public void loadImage(String uri , ImageLoadingListener listener){ // imageLoader.loadImage(uri, listener); options = new DisplayImageOptions.Builder() .showStubImage(R.drawable.default_photo_small) .showImageForEmptyUri(R.drawable.default_photo_small) .showImageOnFail(R.drawable.default_photo_small) // .resetViewBeforeLoading(true) .cacheOnDisc(true) .cacheInMemory(true) .imageScaleType(ImageScaleType.EXACTLY) // .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // .bitmapConfig(Bitmap.Config.RGB_565) // .displayer(new FadeInBitmapDisplayer(300)) .resetViewBeforeLoading(true) .build(); imageLoader.loadImage(uri, options, listener); } }
记得在Application类里加上初始化代码:
UniversalImageLoaderUtil.getInstance().setContext(this);
相关推荐
**Android-Universal-Image-Loader 图片异步加载库详解** 在Android开发中,图片的加载和显示是一项常见的任务,特别是在处理大量图片或者网络图片时,如何高效、流畅地加载和展示图片至关重要。为此,开发者社区...
**Android-Universal-Image-Loader (UIL) 是一个强大的图片加载、缓存和显示库,专为Android平台设计。这个库被广泛使用,因为它能够高效地处理图片资源,避免内存溢出,同时支持多种加载策略和显示选项。** 在...
《Android-Universal-Image-Loader:高效加载...通过学习和使用Android-Universal-Image-Loader,开发者可以构建出更加流畅、用户体验优良的应用,尤其是在处理大量图片时,其强大的功能和优秀的性能将体现得尤为明显。
《Android-Universal-Image-Loader:解决Android应用中的图片内存溢出问题》 在Android开发中,图片加载是一项常见的任务,然而,不当的图片处理方式往往会导致内存溢出(Out of Memory,简称OOM)问题,严重影响...
**Android-Universal-Image-Loader** 是一个广泛使用的开源库,专门为Android应用程序设计,用于高效、灵活地加载、缓存和显示网络、本地存储或资源中的图像。这个库解决了Android平台上的图片异步加载问题,避免了...
Android-Universal-Image-Loader(UIL)是一款广泛应用于Android开发中的图片加载库,它提供了强大的功能,包括异步加载、缓存策略、错误处理以及多种显示选项,使得开发者能够更高效、灵活地处理应用程序中的图像...
总之,`Universal Image Loader`是Android开发中的利器,通过其强大的功能和高度的可定制性,可以帮助开发者高效地处理图片加载和缓存问题,提升用户体验。在实际开发中,结合`UniversalImageLoader`的源代码学习,...
Android-Universal-Image-Loader(UIL)就是这样一款强大的开源库,它专门用于处理Android应用中的图片异步加载和缓存问题。 1. 图片异步加载 Android-Universal-Image-Loader的核心特性之一就是支持图片的异步加载...
《Android-Universal-Image-Loader:高效图片加载与缓存框架解析》 在移动应用开发中,图片加载和缓存是至关重要的环节,特别是在Android平台上,由于设备性能和网络环境的差异,良好的图片管理策略能显著提升用户...
然而,随着Android SDK的发展,现在还有其他如Glide、Picasso等更现代的库,它们在性能和易用性上可能更具优势,但Android-Universal-Image-Loader的历史地位和其对复杂场景的支持仍然值得我们学习和参考。
"Android-Universal-Image-Loader"库就是一个强大的解决方案,它专为Android平台设计,用于实现图片的异步加载、缓存和显示,从而提高应用性能并优化用户体验。这个库由Sergey Tarasevich开发,自2011年以来,已经...
**Android-Universal-Image-Loader** 是一个强大的开源库,专为Android应用设计,用于高效、灵活地加载、缓存和显示网络上的图片。这个库由Sergey Tarasevich开发,它解决了Android应用程序在处理大量图片时可能出现...
《Android-Universal-Image-Loader:打造高效图片加载框架》 在移动开发领域,尤其是在Android平台上,图片加载是一项至关重要的任务。用户界面的美观度、应用的流畅性往往与图片处理息息相关。Android-Universal-...
"Android-Universal-Image-Loader"(简称UIL)是一个强大的图片加载、缓存库,专为解决这个问题而设计。这个库提供了丰富的功能,可以方便地在Android Studio项目中集成,使得图片的异步加载和缓存变得简单高效。 ...