文档章节

android之图片异步加载并缓存到本地

感觉太煽情
 感觉太煽情
发布于 2015/09/24 11:29
字数 832
阅读 455
收藏 7

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

           首先看一下异步加载缓存本地代码:

public class AsyncBitmapLoader  
{  
    /** 
     * 内存图片软引用缓冲 
     */  
    private HashMap<String, SoftReference<Bitmap>> imageCache = null;  
      
    public AsyncBitmapLoader()  
    {  
        imageCache = new HashMap<String, SoftReference<Bitmap>>();  
    }  
      
    public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)  
    {  
        //在内存缓存中,则返回Bitmap对象  
        if(imageCache.containsKey(imageURL))  
        {  
            SoftReference<Bitmap> reference = imageCache.get(imageURL);  
            Bitmap bitmap = reference.get();  
            if(bitmap != null)  
            {  
                return bitmap;  
            }  
        }  
        else  
        {  
            /** 
             * 加上一个对本地缓存的查找 
             */  
            String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);  
            File cacheDir = new File("/mnt/sdcard/test/");  
            File[] cacheFiles = cacheDir.listFiles();  
            int i = 0;  
            if(null!=cacheFiles){
            for(; i<cacheFiles.length; i++)  
            {  
                if(bitmapName.equals(cacheFiles[i].getName()))  
                {  
                    break;  
                }  
            }  
              
            if(i < cacheFiles.length)  
            {  
                return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);  
            }
            }
        }  
          
        final Handler handler = new Handler()  
        {  
            /* (non-Javadoc) 
             * @see android.os.Handler#handleMessage(android.os.Message) 
             */  
            @Override  
            public void handleMessage(Message msg)  
            {  
                // TODO Auto-generated method stub  
                imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);  
            }  
        };  
          
        //如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片  
        new Thread()  
        {  
            /* (non-Javadoc) 
             * @see java.lang.Thread#run() 
             */  
            @Override  
            public void run()  
            {  
                // TODO Auto-generated method stub  
                InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);  
                  
                Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);  
                imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));  
                Message msg = handler.obtainMessage(0, bitmap);  
                handler.sendMessage(msg);  
                  
                File dir = new File("/mnt/sdcard/test/");  
                if(!dir.exists())  
                {  
                    dir.mkdirs();  
                }  
                  
                File bitmapFile = new File("/mnt/sdcard/test/" +   
                        imageURL.substring(imageURL.lastIndexOf("/") + 1));  
                if(!bitmapFile.exists())  
                {  
                    try  
                    {  
                        bitmapFile.createNewFile();  
                    }  
                    catch (IOException e)  
                    {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                }  
                FileOutputStream fos;  
                try  
                {  
                    fos = new FileOutputStream(bitmapFile);  
                    bitmap.compress(Bitmap.CompressFormat.PNG,   
                            100, fos);  
                    fos.close();  
                }  
                catch (FileNotFoundException e)  
                {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
                catch (IOException e)  
                {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        }.start();  
          
        return null;  
    }  

    public interface ImageCallBack  
    {  
        public void imageLoad(ImageView imageView, Bitmap bitmap);  
    }  
}

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

public class HttpUtils {

	public static InputStream getStreamFromURL(String imageURL) {
		InputStream in=null;
		try {
			URL url=new URL(imageURL);
			HttpURLConnection connection=(HttpURLConnection) url.openConnection();
			in=connection.getInputStream();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return in;
		
	}
}

这是一个访问网络获取类。不细说了。

   下面看一下如何使用封装好的异步加载图片的类:

public class ImageCacheActivity extends Activity {
    /** Called when the activity is first created. */
	private ListView listview;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        listview=(ListView) findViewById(R.id.listView_list);
        MyAdapter adapter=new MyAdapter();
        listview.setAdapter(adapter);
    }
    
    private class MyAdapter extends BaseAdapter{

    	private AsyncBitmapLoader asyncBitmapLoader;
    	public MyAdapter(){
    		asyncBitmapLoader=new AsyncBitmapLoader();
    	}
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return 10;
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			if(convertView==null){
				convertView=LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_item, null);
			}
			ImageView image=(ImageView) convertView.findViewById(R.id.addexam_list_icon);
			String imageURL="http://s.ata.net.cn/4f98db46908987a21a000003/logo/2012/04/114_80aaf295c083d07a496743699aac3193.png";
			Bitmap bitmap=asyncBitmapLoader.loadBitmap(image, imageURL, new ImageCallBack() {
				
				@Override
				public void imageLoad(ImageView imageView, Bitmap bitmap) {
					// TODO Auto-generated method stub
					imageView.setImageBitmap(bitmap);
				}
			});
			 if(bitmap == null)  
		        {  
				   image.setImageResource(R.drawable.ic_launcher);  
		        }  
		        else  
		        {  
		        	image.setImageBitmap(bitmap);  
		        }  
		          
			return convertView;
		}
    	
    }
}

这样就完成了,网络获取不到bitmap则显示默认图片

哈哈,这样就完成了~

本文转载自:http://blog.csdn.net/wangkuifeng0118/article/details/7648618

感觉太煽情
粉丝 43
博文 102
码字总数 25839
作品 0
临沂
程序员
私信 提问
Android异步下载图片并且缓存图片到本地

在Android开发中我们经常有这样的需求,从服务器上下载xml或者JSON类型的数据,其中包括一些图片资源,本demo模拟了这个需求,从网络上加载XML资源,其中包括图片,我们要做的解析XML里面的数...

liuher
2014/07/23
56
0
android应用开发 网络编程与常见功能优化总结

一般的应用都是从服务器获取数据,然后通过极致的界面风格,将数据清晰,明朗的展现给用户。、 那么就可以分为这两块: 1.界面UI 追求极致 2.功能 2.1获取数据:主要是与服务器通信,那么就要...

补全
2013/04/07
585
1
六款值得推荐的android(安卓)开源框架简介【转】

1、volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载; (2) 网络请求的排序(scheduling) (3) 网络请求的优先级处理 (4) 缓存 (5) 多级别取消请求...

hkstar35
2014/07/11
290
0
六款值得推荐的android(安卓)开源框架简介【转】

1、volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载; (2) 网络请求的排序(scheduling) (3) 网络请求的优先级处理 (4) 缓存 (5) 多级别取消请求...

火蚁
2014/07/09
668
1
GridView加载大量图片卡顿问题

1 在异步加载之前的代码的和普通加载代码一样,只需要在GirdView的Adapter的public View getView(int position, View convertView, ViewGroupparent)方法使用异步加载的方式返回ImageView。 ...

ljrapple
2014/08/12
2.1K
0

没有更多内容

加载失败,请刷新页面

加载更多

程序设计基础(C)第06讲例程

1summing.c /* summing.c -- 根据用户键入的整数求和 */#include <stdio.h>int main(void){ long num; long sum = 0L; /* 把sum 初始化为0 */ int status; p......

树人大学数字媒体吴凡
26分钟前
6
0
聊聊nacos config的publishConfig

序 本文主要研究一下nacos config的publishConfig ConfigController nacos-1.1.3/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java @Controller@R......

go4it
53分钟前
5
0
Eureka应用注册与集群数据同步源码解析

在之前的EurekaClient自动装配及启动流程解析一文中我们提到过,在构造DiscoveryClient类时,会把自身注册到服务端,本文就来分析一下这个注册流程 客户端发起注册 boolean register() t...

Java学习录
今天
11
0
Java描述设计模式(15):责任链模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景描述 1、请假审批流程 公司常见的请假审批流程:请假天数 当 day<=3 天,项目经理审批当 3<day<=5 天,部门经理审批当 day>5 天...

知了一笑
今天
11
0
总结:数组与链表

1、内存申请:数组在内存上是连续的空间;链表,内存地址上可以是不连续的。 2、查询速度:数组可以随机访问,链表必须顺序访问,即从首个元素开始遍历,逐个查找,所以数组查询很快。 3、写入...

浮躁的码农
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部