Android开发之异步加载图片

本次谈一谈Andriod异步加载图片的问题,在这里我们用到的开源框架是Universal-Image-Loader,先贴一下下载地址:

https://github.com/nostra13/Android-Universal-Image-Loader

下面介绍这个框架的使用方法。

一、特点

流程

每一个图片的加载和显示任务都运行在独立的线程中,除非这个图片缓存在内存中,这种情况下图片会立即显示。如果需要的图片缓存在本地,他们会开启一个独立的线程队列。如果在缓存中没有正确的图片,任务线程会从线程池中获取,因此,快速显示缓存图片时不会有明显的障碍。
流程图:

Paste_Image.png

功能特性:

  1. 多线程异步加载和显示图片(图片来源于网络、sd卡、assets文件夹,drawable文件夹(不能加载9patch),新增加载视频缩略图)。
    "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)

  2. 支持通过“listener”监视加载的过程,可以暂停加载图片,在经常使用的ListView、GridView中,可以设置滑动时暂停加载,停止滑动时加载图片(便于节约流量,在一些优化中可以使用)。

  3. 缓存图片至内存时,可以更加高效的工作。

  4. 高度可定制化(可以根据自己的需求进行各种配置,如:线程池,图片下载器,内存缓存策略等)。

  5. 支持图片的内存缓存,SD卡(文件)缓存。

  6. 在网络速度较慢时,还可以对图片进行加载并设置下载监听。

二、使用方法

配置

  1. 下载jar包放在libs文件夹中
    设置权限
    <uses-permissio android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" />
    由于是使用过程中会图片获取要通过网络,并且有缓存设置,所以这2个权限必须要有。
    设置缓存
    File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache");
    然后在ImageLoaderConfiguration中设置缓存路径
  2. 在应用中配置ImageLoaderConfiguration参数(只能配置一次,如多次配置,则默认第一次的配置参数)
    1)使用默认设置
    ImageLoaderConfiguration configuration = ImageLoaderConfiguration.createDefault(this);
    2)自己配置参数

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) // 50 Mb sd卡(本地)缓存的最大值 .diskCacheFileCount(100) // 可以缓存的文件数量 // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密 .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) .imageDownloader(new BaseImageDownloader(context)) // default .imageDecoder(new BaseImageDecoder()) // default .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default .writeDebugLogs() // 打印debug log .build(); //开始构建

  1. 在application中初始化
    ImageLoader.getInstance().init(config);
  2. 图片显示操作
    1)首先要得到ImageLoader的实例(使用单例模式)
    ImageLoader imageLoader = ImageLoader.getInstance();
    2)显示参数配置

DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.ic_stub) // 设置图片下载期间显示的图片 .showImageForEmptyUri(R.drawable.ic_empty) // 设置图片Uri为空或是错误的时候显示的图片 .showImageOnFail(R.drawable.ic_error) // 设置图片加载或解码过程中发生错误显示的图片 .resetViewBeforeLoading(false) // default 设置图片在加载前是否重置、复位 .delayBeforeLoading(1000) // 下载前的延迟时间 .cacheInMemory(false) // default 设置下载的图片是否缓存在内存中 .cacheOnDisk(false) // default 设置下载的图片是否缓存在SD卡中 .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 还可以设置圆角图片new RoundedBitmapDisplayer(20) .handler(new Handler()) // default .build();
注:如果DisplayImageOption没有传递给ImageLoader.displayImage(…)方法,那么从配置默认显示选项(ImageLoaderConfiguration.defaultDisplayImageOptions(…))将被使用。
参数补充:
一).imageScaleType(ImageScaleType imageScaleType) //设置图片的缩放方式 缩放类型mageScaleType: EXACTLY :图像将完全按比例缩小的目标大小 EXACTLY_STRETCHED:图片会缩放到目标大小完全 IN_SAMPLE_INT:图像将被二次采样的整数倍 IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小 NONE:图片不会调整 二).displayer(BitmapDisplayer displayer) //设置图片的显示方式 显示方式displayer: RoundedBitmapDisplayer(int roundPixels)设置圆角图片 FakeBitmapDisplayer()这个类什么都没做 FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间 SimpleBitmapDisplayer()正常显示一张图片 三).considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转)
3)显示图片
1、 ImageLoader.getInstance().displayImage(uri, imageView); 2、 ImageLoader.getInstance().displayImage(uri, imageView, options); 3、 ImageLoader.getInstance().displayImage(uri, imageView, listener); 4、 ImageLoader.getInstance().displayImage(uri, imageView, options, listener); 5、 ImageLoader.getInstance().displayImage(uri, imageView, options, listener, progressListener);
参数解析
imageUrl 图片的URL地址� imageView 显示图片的ImageView控件 options DisplayImageOptions配置信息 listener 图片下载情况的监听 progressListener 图片下载进度的监听
a.方法1:最简单的方式,我们只需要定义要显示的图片的URL和要显示图片的ImageView。这种情况下,图片的显示选项会使用默认的配置
b.方法2:加载自定义配置的一个图片
c.方法3:加载带监听的一个图片
d.方法4:加载自定义配置且带监听的一个图片
e. 方法5:加载自定义配置且带监听和进度条的一个图片

ImageLoader.getInstance().displayImage(uri, imageView, 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 arg2) { //加载成功 } @Override public void onLoadingCancelled(String arg0, View arg1) { //加载取消 } }, new ImageLoadingProgressListener() { @Override public void onProgressUpdate(String imageUri, View view, int current, int total) { //加载进度 } });

三、注意事项

  1. 假如经常出现OOM,可尝试以下方法:
  1. 减少配置之中线程池的大小,(.threadPoolSize).推荐1-5;
  1. 使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
  2. 使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者 try.imageScaleType(ImageScaleType.EXACTLY);
  3. 避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象;
  4. 使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();
  1. 内存缓存模式可以使用以下已实现的方法 (ImageLoaderConfiguration.memoryCache(...))
    1)缓存只使用强引用
    LruMemoryCache (缓存大小超过指定值时,删除最近最少使用的bitmap) --默认情况下使用
    2)缓存使用弱引用和强引用
    UsingFreqLimitedMemoryCache (缓存大小超过指定值时,删除最少使的bitmap) �LRULimitedMemoryCache (缓存大小超过指定值时,删除最近最少使用的<span style="font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">bitmap) --默认值</span> �FIFOLimitedMemoryCache (缓存大小超过指定值时,按先进先出规则删除的<span style="font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">bitmap)</span> LargestLimitedMemoryCache (缓存大小超过指定值时,删除最大的bitmap) LimitedAgeMemoryCache (缓存对象超过定义的时间后删除)
    3)缓存使用弱引用
    WeakMemoryCache(没有限制缓存)
  2. 本地缓存模式可以使用以下已实现的方法 (ImageLoaderConfiguration.diskCache(...))
    UnlimitedDiskCache 不限制缓存大小(默认) TotalSizeLimitedDiskCache (设置总缓存大小,超过时删除最久之前的缓存) FileCountLimitedDiskCache (设置总缓存文件数量,当到达警戒值时,删除最久之前的缓存。如果文件的大小都一样的时候,可以使用该模式) LimitedAgeDiskCache (不限制缓存大小,但是设置缓存时间,到期后删除)
有一份源码可做参考:点击下载
以上就是今天的全部内容了。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,468评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,620评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,427评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,160评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,197评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,334评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,775评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,444评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,628评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,459评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,508评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,210评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,767评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,850评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,076评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,627评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,196评论 2 341

推荐阅读更多精彩内容