首页 >> 大全

Android 异步加载图片-LruCache和SD卡或手机缓存

2023-11-30 大全 22 作者:考证青年

利用和使用图片加载的三级缓存

异步加载图片的例子,网上也比较多,大部分用了> ,但是现在已经不再推荐使用这种方式了,因为从.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。另外, 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,这就有潜在的风险造成应用程序的内存溢出并崩溃,所以我这里用得是来缓存图片,当存储Image的大小大于设定的值,系统自动释放内存,这个类是3.1版本中提供的,如果你是在更早的版本中开发,则需要导入--v4的jar包(这里要注意咯)

为什么写这篇文章呢?

因为我之前做的项目中,也有异步加载图片,那时候用得是去下载图片,每次下载图片都要new 去下载,而且还是并发去下载,每次都new 一个线程浪费内存,老板说服务器承受不起这么多的连接,叫我改成先获取一张图片之后再去获取下一张,这样子保存与服务器的连接为一个,服务器压力小了,然后楼主就想到线程池,线程池很好的帮我们管理并发的问题,并发的问题解决了,可是后面又出问题了,图片多了就出现OOM()异常,之后用了,先用中获取图片,没有就开线程去下载,老板说你为什么不把图片在手机上做个缓存呢,于是我用了手机缓存,大概思路就是先从中获取图片,如果没有就去手机缓存中获取,手机缓存中没有就开启先从去下载,然后成功的解决了OOM的问题,前些天老板要我重构下代码,我也觉得之前写的代码耦合性太强,早就想改,然后之前看到的照片墙应用实现,再多的图片也不怕崩溃的这篇文章,和滑动过程中取消下载任务,停下来的时候才去下载这2点比较好,值得我学习,然后我就将我的项目异步加载这一块改了下,发到这里做个记录吧,以后类似的异步加载图片直接拷贝代码,提交开发的效率

这篇文章做了哪些方面的优化

使用了线程池来管理下载任务使用来缓存图片使用手机来缓存图片滑动的时候取消下载任务,静止的时候进行下载,滑动更加的流畅降低了代码的耦合性,结构更加的清晰,便于以后重用

接下来我们先来看看项目的结构

缓存导致页面加载出现问题了__加载缓冲的图片头像

[java] view plain copy

。。; 。io。File; 。io。; 。io。; 。。; 。。; 。。。; 。。; 。os。; { /** *sd卡的根目录 */ =。()。(); /** *手机的缓存根目录 */ =null; /** *保存Image的目录名 */ ="/"; (){ =。

()。(); } /** *获取储存Image的目录 *@ */ (){ 。ate()。(。)? +:+; } /** *保存Image的方法,有sd卡存储到sd卡,没有就存储到手机目录 *@ *@ *@ */ (,){ if(==null){ ; } =(); =(path); if(!。()){ 。

mkdir(); } =(path+File。+); file。(); =(file); 。(。JPEG,100,fos); fos。flush(); fos。close(); } /** *从手机或者sd卡获取 *@ *@ */ p(){ 。(()+File。+); } /** *判断文件是否存在 *@ *@ */ xists(){ (()+File。

+)。(); } /** *获取文件的大小 *@ *@ */ e(){ (()+File。+)。(); } /** *删除SD卡或者手机的缓存图片和目录 */ (){ =(()); if(!。()){ ; } if(。()){ []=。list(); for(inti=0;i

[java] view plain copy

。。; { ing[]=[]{ "。。com/-////s160-c/A%。jpg", "。。com/--///-/s160-c/A%%%%%。jpg", "。。com/-////s160-c/%%。

jpg", "。。com/--////s160-c/%。jpg", "。。com/-8HO-////s160-c/%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/Apre%%%%。jpg", "。

。com/-s-/-JI///s160-c/%。jpg", "。。com/-////s160-c/Bee%%。jpg", "。。com/-/-I///s160-c/%%。jpg", "。。com/-////s160-c/。jpg", "。。com/-////s160-c/Chess。

jpg", "。。com/-/-QmDI//E-/s160-c/。jpg", "。。com/-////s160-c/%。jpg", "。。com/-/URquh-kVvoI///s160-c/%%。jpg", "。。com/-////s160-c/%%。jpg", "。。

com/-////s160-c/。jpg", "。。com/-////s160-c/Death%%-%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/。jpg", "。。com/-////s160-c/Eagle%%。

jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/False%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/Foggy%。jpg", "。。

com/-////s160-c/。jpg", "。。com/-////s160-c/%%。jpg", "。。com/-////s160-c/%%。jpg", "。。com/-/-zI///s160-c/%。jpg", "。。com/-////s160-c/Grand%。

jpg", "。。com/-////s160-c/Grass%。jpg", "。。com/-////s160-c/Green%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/%%。

jpg", "。。com/-/-QXbI///s160-c/%。jpg", "。。com/-////s160-c/Into%%。jpg", "。。com/-////s160-c/Jelly%%。jpg", "。。com/-///-tsGE/s160-c/Jelly%%。jpg", "。

。com/-////s160-c/Kauai。jpg", "。。com/-///cktDy-ysfHo/s160-c/Kyoto%。jpg", "。。com/-////s160-c/Lake%%。jpg", "。。com/-////s160-c/Lava%%%。jpg", "。。com/-/-5I//j-/s160-c/Leica%%。

jpg", "。。com/-////s160-c/Leica%%。jpg", "。。com/-////s160-c/Leica%%%%。jpg", "。。com/-////s160-c/Light%%。jpg", "。。com/-////s160-c/%%%。

jpg", "。。com/-////s160-c/Lone%%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-erbF--z-W4s////s160-c/%。jpg", "。。com/-////s160-c/Look%%%%。jpg", "。

。com/-////s160-c/Lost%%%。jpg", "。。com/-////s160-c/%%。jpg", "。。com/-////s160-c/Mono%%。jpg", "。。com/-////s160-c/%%。

jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/One%。jpg", "。。com/-////s160-c/Open%。jpg", "。。com/-////s160-c/%。

jpg", "。。com/-////s160-c/。jpg", "。。com/-////s160-c/Over%。jpg", "。。com/-cauH-////s160-c/。jpg", "。。com/-///iVZE-/s160-c/。jpg", "。。com/-////s160-c/。

jpg", "。。com/-////s160-c/Rice%。jpg", "。。com/-////s160-c/%%。jpg", "。。com/-///-c9o/s160-c/%。jpg", "。。com/-/URqu-///s160-c/%%。jpg", "。

。com/--RE///Dg2Fv-JxOeg/s160-c/%%。jpg", "。。com/-////s160-c/Rust%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/。jpg", "。。com/-Iwi6-////s160-c/%。

jpg", "。。com/-////s160-c/%。jpg", "。。com/-///v-/s160-c/%。jpg", "。。com/-////s160-c/Sin%。jpg", "。。com/-////s160-c/%。jpg", "。。

com/-////s160-c/%。jpg", "。。com/-////s160-c/。jpg", "。。com/-////s160-c/Strip%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-7-////s160-c/%%。

jpg", "。。com/--Pok////s160-c/%。jpg", "。。com/-B1HW-////s160-c/The%%。jpg", "。。com/-PO4E-////s160-c/The%。jpg", "。。com/-////s160-c/The%%%。jpg", "。

。com/-G-////s160-c/The%。jpg", "。。com/-h-////s160-c/Tokyo%。jpg", "。。com/-Hy9k-////s160-c/Tokyo%。jpg", "。。com/-////s160-c/Tokyo%。jpg", "。。com/-FB-////s160-c/Tufa%%。

jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/%。jpg", "。。com/-////s160-c/。jpg", "。。com/-////s160-c/。jpg", "。。com/-////s160-c/Yet%%%。

jpg", "。。com/-////s160-c/%。jpg",}; }"font-:;font-size:14px;">

[java] view plain copy

。。; 。io。; 。net。; 。net。URL; 。util。。; 。util。。; 。。; 。。; 。。; 。os。; 。os。; 。。v4。util。; { /** *缓存Image的类,当存储Image的大小大于设定的值,系统自动释放内存 */ ; /** *操作文件相关类对象的引用 */ Utils; /** *下载Image的线程池 */ =null; r(){ //获取系统分配给每个应用程序的最大内存,每个应用系统分配32M =(int)。

()。(); =/8; //给分配1/84M =(){ //必须重写此方法,来测量的大小 @ (,){ 。()*value。(); } }; =(); } /** *获取线程池的方法,因为涉及到并发的问题,我们加上同步锁 *@ */ (){ if(==null){ (。class){ if(==null){ //为了下载图片更加的流畅,我们用了2个线程来下载图片 =。

(2); } } } ol; } /** *添加到内存缓存 *@ *@ */ (,){ if(e(key)==null&&!=null){ 。put(key,); } } /** *从内存缓存中获取一个 *@ *@ */ (){ 。get(key); } /** *先从内存缓存中获取,如果没有就从SD卡或者手机缓存中获取,SD卡或者手机缓存 *没有就去下载 *@ *@ *@ */ Image(,){ //替换Url中非字母和非数字的字符,这里比较重要,因为我们用Url作为文件名,比如我们的Url //是;用这个作为图片名称,系统会认为为一个目录, //我们没有创建此目录保存文件就会报错 =url。

("[^\\w]",""); =(); if(!=null){ ; }else{ =(){ @ age(){ super。(msg); 。(()msg。obj,url); } }; ()。((){ @ (){ =(url); =。(); msg。obj=; 。(msg); try{ //保存在SD卡或者手机目录 。(,); }catch(){ e。

(); } //将加入内存缓存 he(,); } }); } ; } /** *获取,内存中没有就去手机或者sd卡中获取,这一步在中会调用,比较关键的一步 *@ *@ */ (){ if(e(url)!=null){ (url); }(。(url)&&。(url)!=0){ //从SD卡获取手机里面获取 =。(url); //将加入内存缓存 he(url,); ; } ; } /** *从Url中获取 *@ *@ */ (){ =null; =null; try{ =(url); con=()。

(); con。(10*1000); con。(10*1000); con。(true); con。(true); =。(con。()); }catch(){ e。(); }{ if(con!=null){ con。(); } } ; } /** *取消正在下载的任务 */ (){ if(!=null){ 。(); =null; } } /** *异步下载图片的回调接口 *@ * */ { (,); } }

中有几个方法比较重要 首先我们需要重写( key, value)来计算图片的大小,默认返回图片的数量(final url, final r )先去查看Image,没有再去手机缓存中查看,在没有则开启线程下载,这里我们提供了一个回调接口,回调方法中我们将和图片Url作为参数, = url.("[^\\w]", "") 我在代码中注释写的比较清楚( url)方法,此方法在中的()当中调用,如果()中不调用此方法试试你就知道效果

[java] view plain copy

..; ..; ..; .view.View; .view.; ..; ...; ..; ..; ..; ....r; { /** *上下文对象的引用 */ t; /** *的数组 */ []; /** *对象的应用 */ View; /** *Image下载器 */ ; /** *记录是否刚打开程序,用于解决进入程序不滚动屏幕,不会下载图片的问题。

*参考# */ =true; /** *一屏中第一个item的位置 */ ; /** *一屏中所有item的个数 */ ; (,,[]){ this.=; this.=; this.=; =(); .(this); } @ (,){ //仅当静止时才去下载图片,滑动时取消所有正在下载的任务 if(==..){ (,); }else{ (); } } /** *滚动的时候调用的方法,刚开始显示也会调用此方法 */ @ (,, ,){ =; =; //因此在这里为首次进入程序开启下载任务。

if(&&>0){ (,); =false; } } @ (){ .; } @ (){ []; } @ (){ ; } @ (,,){ ; =[]; if(==null){ =(); }else{ =(); } .(.(150,150)); .(..); //给设置Tag,这里已经是司空见惯了 .(); /*******************************去掉下面这几行试试是什么效果****************************/ =.(.("[^\\w]","")); if(!=null){ .(); }else{ .(.().(R..)); } /**********************************************************************************/ ; } /** *显示当前屏幕的图片,先会去查找,没有就去sd卡或者手机目录查找,在没有就开启线程去下载 *@m *@t */ (,){ =null; for(inti=;i =[i]; View=().(); =.(,ener(){ @ der(,){ if(!=null&&!=null){ .(); } } }); //if(!=null){ //.(); //}else{ //.(.().(R..)); //} } } /** *取消下载任务 */ (){ .(); } }

[java] view plain copy

。。; 。app。; 。os。; 。view。Menu; 。view。; 。。; 。。Toast; { View; []=。; ; Utils; @ e(tate){ super。(); (R。。

); =(this); =()(R。id。); =(this,,); 。(); } @ oy(){ 。(); super。(); } @ (){ super。(menu); menu。add("删除手机中图片缓存"); 。(menu); } @ (){ (item。

()){ case0: 。(); Toast。((),"清空缓存成功",Toast。)。show(); break; } 。d(item); } }"font-:;font-size:14px;">

[html] view plain copy

[html] view plain copy

好了,代码就全部介绍完了,我们运行下程序看看效果,这里的效果是用一个线程下载图片的效果,可能有一些不完整,想看看效果自己动手试试,郁闷,家里的网络卡,gif的图片出不来效果,只能明天上传图片啦,公司也上传不了动画效果,我去,那我就贴一张普通图片,哈哈

缓存导致页面加载出现问题了_加载缓冲的图片头像_

好了,今天的讲解到此结束,有疑问的朋友请在下面留言,源码里面的布局文件 设置了,有点丑,大家可以改成90dip

源码下载,点击这里

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了