ListView异步加载远端图片

LoadRemoteImage

公有成员方法setRemoteImageListener用于监听远端图片

传入两个参数:String url 图片URL地址  OnRemoteImageListener listener OnRemoteImageListener接口

 

线程Runnable接口处理流程图:

 

 

 

Java代码   收藏代码
  1. package lizhen.dg;  
  2.   
  3. import java.util.concurrent.ExecutorService;  
  4. import java.util.concurrent.Executors;  
  5.   
  6. import org.apache.http.HttpResponse;  
  7. import org.apache.http.HttpStatus;  
  8. import org.apache.http.client.HttpClient;  
  9. import org.apache.http.client.methods.HttpGet;  
  10. import org.apache.http.impl.client.DefaultHttpClient;  
  11. import org.apache.http.util.EntityUtils;  
  12.   
  13. import android.graphics.Bitmap;  
  14. import android.graphics.BitmapFactory;  
  15. import android.os.Handler;  
  16. import android.os.Message;  
  17.   
  18. /** 
  19.  * 遠端圖片類 
  20.  * */  
  21. public class LoadRemoteImage {  
  22.   
  23.     private ExecutorService pool; //線程池  
  24.       
  25.     private final int MESSAGE_OK = 1//遠端圖片獲取成功消息  
  26.     private final int MESSAGE_ERROR = -1//遠端圖片獲取錯誤消息  
  27.       
  28.     private ImageBuffer imageBuffer; //圖片緩存  
  29.       
  30.       
  31.     /** 
  32.      * 構造函數 
  33.      * 執行初始化操作 
  34.      * */  
  35.     public LoadRemoteImage() {  
  36.         pool = Executors.newCachedThreadPool();  
  37.         imageBuffer = new ImageBuffer();  
  38.     }  
  39.       
  40.     /** 
  41.      * 設置遠端圖片事件監聽器 
  42.      * @param url 圖像URL地址 
  43.      * @param listener 遠端圖片監聽器 
  44.      * */  
  45.     public void setRemoteImageListener(final String url, final OnRemoteImageListener listener) {  
  46.           
  47.         /* 
  48.          * 遠端圖片消息處理Handler 
  49.          * */  
  50.         final Handler handler = new Handler() {  
  51.   
  52.             @Override  
  53.             public void handleMessage(Message msg) {  
  54.                 super.handleMessage(msg);  
  55.                 int what = msg.what;  
  56.                 switch(what) {  
  57.                 case MESSAGE_OK : //成功   
  58.                     listener.onRemoteImage((Bitmap) msg.obj); //調用onRemoteImage回調方法  
  59.                     break;  
  60.                 case MESSAGE_ERROR : //錯誤  
  61.                     listener.onError((String) msg.obj); 調用onError回調方法  
  62.                     break;  
  63.                 }  
  64.             }  
  65.               
  66.         };  
  67.           
  68.         /* 
  69.          * 向線程池中添加新任務 
  70.          * 下載給定URL地址圖片 
  71.          * */  
  72.         pool.execute(new Runnable() {  
  73.               
  74.             @Override  
  75.             public void run() {  
  76.                 try {  
  77.                     Bitmap image = null;  
  78.                     /* 
  79.                      * 如果圖片緩存中沒有該圖片,則下載放入緩存中 
  80.                      * */  
  81.                     if((image = imageBuffer.get(url)) == null) {  
  82.                         byte[] resource = httpRequestByteArray(url); //HTTP請求圖片字節數據  
  83.                         image = optimizeBitmap(resource, 100100); //獲得優化的圖像  
  84.                         imageBuffer.put(url, image);  
  85.                     }  
  86.                     handler.sendMessage(handler.obtainMessage(MESSAGE_OK, image)); //遠端圖像下載成功  
  87.                 } catch (Exception e) {  
  88.                     /* 
  89.                      * 異常處理 
  90.                      * */  
  91.                     handler.sendMessage(handler.obtainMessage(MESSAGE_ERROR, e.getMessage()));  
  92.                     return;  
  93.                 }  
  94.             }  
  95.         });  
  96.     }  
  97.       
  98.     /**  
  99.      * 使用HTTP GET方式請求  
  100.      * @param url URL地址  
  101.      * @return HttpEntiry對象  
  102.      * @throws Exception  
  103.      * */    
  104.     private byte[] httpRequestByteArray(String url) throws Exception {    
  105.         byte[] result = null;    
  106.         HttpGet httpGet = new HttpGet(url);    
  107.         HttpClient httpClient = new DefaultHttpClient();    
  108.         HttpResponse httpResponse;    
  109.         httpResponse = httpClient.execute(httpGet);    
  110.         int httpStatusCode = httpResponse.getStatusLine().getStatusCode();    
  111.         /*  
  112.          * 判斷HTTP狀態碼是否為200  
  113.          * */    
  114.         if(httpStatusCode == HttpStatus.SC_OK) {    
  115.             result = EntityUtils.toByteArray(httpResponse.getEntity());    
  116.         } else {  
  117.             throw new Exception("HTTP: "+httpStatusCode);  
  118.         }  
  119.         return result;    
  120.     }  
  121.       
  122.     private Bitmap optimizeBitmap(byte[] resource, int maxWidth, int maxHeight) {    
  123.         Bitmap result = null;    
  124.         int length = resource.length;    
  125.         BitmapFactory.Options options = new BitmapFactory.Options();        
  126.         options.inJustDecodeBounds = true;    
  127.         result = BitmapFactory.decodeByteArray(resource, 0, length, options);    
  128.         int widthRatio = (int) Math.ceil(options.outWidth / maxWidth);    
  129.         int heightRatio = (int) Math.ceil(options.outHeight / maxHeight);    
  130.         if(widthRatio > 1 || heightRatio > 1) {    
  131.             if(widthRatio > heightRatio) {    
  132.                 options.inSampleSize = widthRatio;    
  133.             } else {    
  134.                 options.inSampleSize = heightRatio;    
  135.             }    
  136.         }    
  137.         options.inJustDecodeBounds = false;    
  138.         result = BitmapFactory.decodeByteArray(resource, 0, length, options);    
  139.         return result;    
  140.     }  
  141.       
  142.     /** 
  143.      * 遠端圖片監聽器 
  144.      * */  
  145.     public interface OnRemoteImageListener {  
  146.           
  147.         /** 
  148.          * 遠端圖片處理 
  149.          * @param image 位圖圖片 
  150.          * */  
  151.         void onRemoteImage(Bitmap image);  
  152.           
  153.         /** 
  154.          * 錯誤處理 
  155.          * @param error 錯誤信息 
  156.          * */  
  157.         void onError(String error);  
  158.           
  159.     }  
  160.       
  161. }  

 

ImageBuffer 图片缓存

String键->SoftReference<Bitmap>值储存缓存图片

SoftReference软引用

在内存吃紧抛出“OutOfMemory”异常之前,会被JVM回收,此时调用get方法会返回null

 

 

Java代码   收藏代码
  1. package lizhen.dg;  
  2.   
  3. import java.lang.ref.SoftReference;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import android.graphics.Bitmap;  
  8.   
  9. /** 
  10.  * 圖片緩存類 
  11.  * */  
  12. public class ImageBuffer {  
  13.       
  14.     private Map<String, SoftReference<Bitmap>> buffer = new HashMap<String, SoftReference<Bitmap>>(); //圖片緩存  
  15.   
  16.     /** 
  17.      * 將圖片放進緩存中 
  18.      * @param key 鍵值 
  19.      * @param image Bitmap位圖 
  20.      * */  
  21.     public void put(String key, Bitmap image) {  
  22.         SoftReference<Bitmap> reference = new SoftReference<Bitmap>(image);  
  23.         synchronized(buffer) {  
  24.             buffer.put(key, reference);  
  25.         }  
  26.     }  
  27.   
  28.     /** 
  29.      * 從緩存中取得圖片 
  30.      * @param key 鍵值 
  31.      * @return Bitmap位圖 
  32.      * */  
  33.     public Bitmap get(String key) {  
  34.         Bitmap result = null;  
  35.         synchronized(buffer) {  
  36.             if(buffer.containsKey(key)) {  
  37.                 result = buffer.get(key).get();  
  38.             }  
  39.         }  
  40.         return result;  
  41.     }  
  42.   
  43. }  

 

ListActivity

ListView列表异步加载远端图片

 

Java代码   收藏代码
  1. package lizhen.dg;  
  2.   
  3. import android.app.ListActivity;  
  4. import android.content.Context;  
  5. import android.graphics.Bitmap;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.BaseAdapter;  
  10. import android.widget.ImageView;  
  11. import android.widget.Toast;  
  12.   
  13. public class Main extends ListActivity {  
  14.       
  15.     private String data[] = {  
  16.             "http://192.168.211.86/pic/0.jpg"  
  17.             , "http://192.168.211.86/pic/1.jpg"  
  18.             , "http://192.168.211.86/pic/2.jpg"  
  19.             , "http://192.168.211.86/pic/3.jpg"  
  20.             , "http://192.168.211.86/pic/4.jpg"  
  21.             , "http://192.168.211.86/pic/5.jpg"  
  22.             , "http://192.168.211.86/pic/6.jpg"  
  23.             , "http://192.168.211.86/pic/7.jpg"  
  24.             , "http://192.168.211.86/pic/8.jpg"  
  25.             , "http://192.168.211.86/pic/9.jpg"  
  26.             , "http://192.168.211.86/pic/10.jpg"  
  27.             , "http://192.168.211.86/pic/11.jpg"  
  28.             , "http://192.168.211.86/pic/12.jpg" //錯誤的圖片地址  
  29.             };  
  30.       
  31.     @Override  
  32.     public void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.main);  
  35.           
  36.         setListAdapter(new MyListAdapter(this, data));  
  37.     }  
  38.       
  39.     private class MyListAdapter extends BaseAdapter {  
  40.           
  41.         private Context context;  
  42.         private String[] data;  
  43.         private LoadRemoteImage remoteImage;  
  44.           
  45.         public MyListAdapter(Context context, String[] data) {  
  46.             this.context = context;  
  47.             this.data = data;  
  48.             remoteImage = new LoadRemoteImage();  
  49.         }  
  50.   
  51.         @Override  
  52.         public int getCount() {  
  53.             return data.length;  
  54.         }  
  55.   
  56.         @Override  
  57.         public Object getItem(int position) {  
  58.             return data[position];  
  59.         }  
  60.   
  61.         @Override  
  62.         public long getItemId(int position) {  
  63.             return position;  
  64.         }  
  65.   
  66.         @Override  
  67.         public View getView(int position, View convertView, ViewGroup parent) {  
  68.             Holder holder = null;    
  69.             if(convertView == null) {    
  70.                 convertView = getLayoutInflater().inflate(R.layout.item, parent, false);    
  71.                 holder = new Holder(convertView);    
  72.                 convertView.setTag(holder);    
  73.             } else {    
  74.                 holder = (Holder) convertView.getTag();    
  75.             }  
  76.             final ImageView icon = holder.getIcon();  
  77.             icon.setImageResource(R.drawable.icon);  
  78.             remoteImage.setRemoteImageListener((String) getItem(position), new LoadRemoteImage.OnRemoteImageListener() {  
  79.                   
  80.                 @Override  
  81.                 public void onError(String error) {  
  82.                     Toast.makeText(context, error, Toast.LENGTH_LONG).show();  
  83.                 }  
  84.   
  85.                 @Override  
  86.                 public void onRemoteImage(Bitmap image) {  
  87.                     icon.setImageBitmap(image);  
  88.                 }  
  89.             });  
  90.             holder.getName().setText((String) getItem(position));    
  91.             return convertView;    
  92.         }  
  93.           
  94.     }  
  95.       
  96. }  

 

Java代码   收藏代码
  1. package lizhen.dg;  
  2.   
  3. import android.view.View;  
  4. import android.widget.ImageView;  
  5. import android.widget.TextView;  
  6.   
  7. public class Holder {  
  8.     private View parentView;    
  9.     private ImageView iconImageView;    
  10.     private TextView labelTextView;    
  11.         
  12.     public Holder(View view) {    
  13.         this.parentView = view;    
  14.     }    
  15.         
  16.     public ImageView getIcon() {    
  17.         if(iconImageView == null) {    
  18.             iconImageView = (ImageView) parentView.findViewById(R.id.item_IconImageView);    
  19.         }    
  20.         return iconImageView;    
  21.     }    
  22.         
  23.     public TextView getName() {    
  24.         if(labelTextView == null) {    
  25.             labelTextView = (TextView) parentView.findViewById(R.id.item_NameTextView);    
  26.         }    
  27.         return labelTextView;    
  28.     }    
  29. }  
 

运行结果:

转自http://dyingbleed.iteye.com/blog/1183481

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值