欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android异步加载图片并缓存到本地实现方法

程序员文章站 2023-12-14 18:38:52
在android项目中访问网络图片是非常普遍性的事情,如果我们每次请求都要访问网络来获取图片,会非常耗费流量,而且图片占用内存空间也比较大,图片过多且不释放的话很容易造成内...
在android项目中访问网络图片是非常普遍性的事情,如果我们每次请求都要访问网络来获取图片,会非常耗费流量,而且图片占用内存空间也比较大,图片过多且不释放的话很容易造成内存溢出。针对上面遇到的两个问题,首先耗费流量我们可以将图片第一次加载上面缓存到本地,以后如果本地有就直接从本地加载。图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用lru缓存策略或懒加载缓存策略。今天首先介绍一下本地缓存图片。
首先看一下异步加载缓存本地代码:
复制代码 代码如下:

publicclassasyncbitmaploader
{
/**
*内存图片软引用缓冲
*/
privatehashmap<string,softreference<bitmap>>imagecache=null;
publicasyncbitmaploader()
{
imagecache=newhashmap<string,softreference<bitmap>>();
}
publicbitmaploadbitmap(finalimageviewimageview,finalstringimageurl,finalimagecallbackimagecallback)
{
//在内存缓存中,则返回bitmap对象
if(imagecache.containskey(imageurl))
{
softreference<bitmap>reference=imagecache.get(imageurl);
bitmapbitmap=reference.get();
if(bitmap!=null)
{
returnbitmap;
}
}
else
{
/**
*加上一个对本地缓存的查找
*/
stringbitmapname=imageurl.substring(imageurl.lastindexof("/")+1);
filecachedir=newfile("/mnt/sdcard/test/");
file[]cachefiles=cachedir.listfiles();
inti=0;
if(null!=cachefiles){
for(;i<cachefiles.length;i++)
{
if(bitmapname.equals(cachefiles[i].getname()))
{
break;
}
}
if(i<cachefiles.length)
{
returnbitmapfactory.decodefile("/mnt/sdcard/test/"+bitmapname);
}
}
}
finalhandlerhandler=newhandler()
{
/*(non-javadoc)
*@seeandroid.os.handler#handlemessage(android.os.message)
*/
@override
publicvoidhandlemessage(messagemsg)
{
//todoauto-generatedmethodstub
imagecallback.imageload(imageview,(bitmap)msg.obj);
}
};
//如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片
newthread()
{
/*(non-javadoc)
*@seejava.lang.thread#run()
*/
@override
publicvoidrun()
{
//todoauto-generatedmethodstub
inputstreambitmapis=httputils.getstreamfromurl(imageurl);
bitmapbitmap=bitmapfactory.decodestream(bitmapis);
imagecache.put(imageurl,newsoftreference<bitmap>(bitmap));
messagemsg=handler.obtainmessage(0,bitmap);
handler.sendmessage(msg);
filedir=newfile("/mnt/sdcard/test/");
if(!dir.exists())
{
dir.mkdirs();
}
filebitmapfile=newfile("/mnt/sdcard/test/"+
imageurl.substring(imageurl.lastindexof("/")+1));
if(!bitmapfile.exists())
{
try
{
bitmapfile.createnewfile();
}
catch(ioexceptione)
{
//todoauto-generatedcatchblock
e.printstacktrace();
}
}
fileoutputstreamfos;
try
{
fos=newfileoutputstream(bitmapfile);
bitmap.compress(bitmap.compressformat.png,
100,fos);
fos.close();
}
catch(filenotfoundexceptione)
{
//todoauto-generatedcatchblock
e.printstacktrace();
}
catch(ioexceptione)
{
//todoauto-generatedcatchblock
e.printstacktrace();
}
}
}.start();
returnnull;
}
publicinterfaceimagecallback
{
publicvoidimageload(imageviewimageview,bitmapbitmap);
}
}

这是一个封装好的异步加载图片类,缓存了两份,一份是使用软引用缓存到内存中,一份是缓存到本地sd卡,如果内存中没有,则从本地查找,如果本地没有则从网络获取图片。
复制代码 代码如下:

publicclasshttputils{
publicstaticinputstreamgetstreamfromurl(stringimageurl){
inputstreamin=null;
try{
urlurl=newurl(imageurl);
httpurlconnectionconnection=(httpurlconnection)url.openconnection();
in=connection.getinputstream();

}catch(exceptione){
//todoauto-generatedcatchblock
e.printstacktrace();
}
returnin;

}
}

这是一个访问网络获取类。不细说了。
下面看一下如何使用封装好的异步加载图片的类:
复制代码 代码如下:

publicclassimagecacheactivityextendsactivity{
/**calledwhentheactivityisfirstcreated.*/
privatelistviewlistview;
@override
publicvoidoncreate(bundlesavedinstancestate){
super.oncreate(savedinstancestate);
setcontentview(r.layout.main);
listview=(listview)findviewbyid(r.id.listview_list);
myadapteradapter=newmyadapter();
listview.setadapter(adapter);
}
privateclassmyadapterextendsbaseadapter{
privateasyncbitmaploaderasyncbitmaploader;
publicmyadapter(){
asyncbitmaploader=newasyncbitmaploader();
}
@override
publicintgetcount(){
//todoauto-generatedmethodstub
return10;
}
@override
publicobjectgetitem(intposition){
//todoauto-generatedmethodstub
returnnull;
}
@override
publiclonggetitemid(intposition){
//todoauto-generatedmethodstub
return0;
}
@override
publicviewgetview(intposition,viewconvertview,viewgroupparent){
//todoauto-generatedmethodstub
if(convertview==null){
convertview=layoutinflater.from(getapplicationcontext()).inflate(r.layout.list_item,null);
}
imageviewimage=(imageview)convertview.findviewbyid(r.id.addexam_list_icon);
stringimageurl="http://s.ata.net.cn/4f98db46908987a21a000003/logo/2012/04/114_80aaf295c083d07a496743699aac3193.png";
bitmapbitmap=asyncbitmaploader.loadbitmap(image,imageurl,newimagecallback(){

@override
publicvoidimageload(imageviewimageview,bitmapbitmap){
//todoauto-generatedmethodstub
imageview.setimagebitmap(bitmap);
}
});
if(bitmap==null)
{
image.setimageresource(r.drawable.ic_launcher);
}
else
{
image.setimagebitmap(bitmap);
}

returnconvertview;
}

}
}

这样就完成了,网络获取不到bitmap则显示默认图片。
android异步加载图片并缓存到本地实现方法 
这是一种很实用的方法,大家自己试试吧!

上一篇:

下一篇: