android之圖片異步加載並緩存到本地

      在android項目中訪問網絡圖片是很是廣泛性的事情,若是咱們每次請求都要訪問網絡來獲取圖片,會很是耗費流量,並且圖片佔用內存空間也比較大,圖片過多且不釋放的話很容易形成內存溢出。針對上面遇到的兩個問題,首先耗費流量咱們能夠將圖片第一次加載上面緩存到本地,之後若是本地有就直接從本地加載。圖片過多形成內存溢出,這個是最不容易解決的,要想一些好的緩存策略,好比大圖片使用LRU緩存策略或懶加載緩存策略。今天首先介紹一下本地緩存圖片。java

           首先看一下異步加載緩存本地代碼:android

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則顯示默認圖片jvm

哈哈,這樣就完成了~async

相關文章
相關標籤/搜索