图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略。今天首先介绍一下本地缓存图片
 
 
在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; 
}


android异步加载图片并缓存到本地实现方法的更多相关文章

  1. 演化理解 Android 异步加载图片(转)

    演化理解 Android 异步加载图片(转)http://www.cnblogs.com/CJzhang/archive/2011/10/20/2218474.html

  2. [Android]异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3574131.html  这个可以实现ImageView异步加载 ...

  3. Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅

      Android 高手进阶(21)  版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处http://blog.csdn.net/xiaanming/article/details ...

  4. 实例演示Android异步加载图片

    本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ...

  5. 实例演示Android异步加载图片(转)

    本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ...

  6. 演化理解 Android 异步加载图片

    原文:http://www.cnblogs.com/ghj1976/archive/2011/05/06/2038738.html#3018499 在学习"Android异步加载图像小结&q ...

  7. wemall app商城源码中基于JAVA的Android异步加载图片管理器代码

    wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...

  8. android异步加载图片

    import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; impo ...

  9. Android批量图片加载经典系列——使用LruCache、AsyncTask缓存并异步加载图片

    一.问题描述 使用LruCache.AsyncTask实现批量图片的加载并达到下列技术要求 1.从缓存中读取图片,若不在缓存中,则开启异步线程(AsyncTask)加载图片,并放入缓存中 2.及时移除 ...

随机推荐

  1. simple python code when @ simplnano

    code: import serial,time,itertools try: ser=serial.Serial(2,115200,timeout=0) except: print 'Open CO ...

  2. ie8 不支持new Date('2012-11-10')

    ie 不支持Date.now()以及Date的一些方法开始是在火狐上使用new Date(Date.now())的的方法,这个写法也很sb,当然了当时也没想太多,比较我不是做前台的Date.now() ...

  3. Geek version acm pc^2 direction for user

    gogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogogo ...

  4. [原创]java WEB学习笔记78:Hibernate学习之路---session概述,session缓存(hibernate 一级缓存),数据库的隔离级别,在 MySql 中设置隔离级别,在 Hibernate 中设置隔离级别

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. UML: 协作图

    摘自http://www.umlonline.org/school/thread-38-1-1.html UML1.1时,协作图英文名字叫:Collaboration Diagram,UML2.0时, ...

  6. android 添加背景音乐

    MediaPlayer mediaPlayer=MediaPlayer.create(MainActivity.this,R.raw.qiji); mediaPlayer.start();

  7. c++中的传参问题

    从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有 ...

  8. 浅谈JavaScript计时器

    JavaScript计时器 1.什么是JavaScript计时器? 在JavaScript中,我们可以在设定的时间间隔之后来执行代码,而不是在函数被调用后立即执行. 2.计时器类型 一次性计时器:仅在 ...

  9. -XX:+PrintGCTimeStamps 打印CG发生的时间戳

    -XX:+PrintGCTimeStamps –打印CG发生的时间戳   –[GC[DefNew: 4416K->0K(4928K), 0.0001897 secs] 4790K->374 ...

  10. 有关git的换行符的处理问题

    签入签出时对换行符的操作: #签出时将LF转换为CRLF,签入时将CRLF转换为LF git config --global core.autocrlf true #签出时不转换,签入时转换为LF g ...