Android ListView 异步图片获取

 Android应用中,从远程获取图片算是经常要用的一个功能,而图片资源往往会消耗比较大的流量,而且如果加载在图片比较多的View中,如ListView GridView WebView中,加载速度会比较缓慢。Android图片加载速度很慢的话,程序很容易就挂掉,等待的用户用户同样会等到崩溃。

我们一般的处理方法是:

异步下载

本地缓存

-----------------------------------------------------------

先说异步下载



 

如一个ListView的异步下载

Java代码   收藏代码
  1. public class AsyncActivity extends Activity  {  
  2.     List<data> insList;  
  3.     private ListView mListView;  
  4.     private ArrayList<data> mListItems;  
  5.     private ItemAdapter mAdapter;  
  6.     private ImageView mLfteView;  
  7.     private ImageView mRightView;  
  8.       
  9.       
  10.   
  11.     private static final int REFRESH_LIST = 1;  
  12.     Handler mHandler = new Handler() {  
  13.         public void handleMessage(android.os.Message msg) {  
  14.             int type = msg.what;  
  15.             switch (type) {  
  16.             case REFRESH_LIST: {  
  17.               
  18.                 if (mListItems.size() > 0) {  
  19.                     mListView.setVisibility(View.VISIBLE);  
  20.                     if (mAdapter== null) {  
  21.                         mAdapter = new Adapter(AsyncActivity.this,  
  22.                                 mListItems);  
  23.                         mListView.setAdapter(mAdapter);  
  24.                     }  
  25.                         mAdapter.notifyDataSetChanged();  
  26.   
  27.                 }  
  28.                 mListView.requestFocus();  
  29.                   
  30.                 unShowDialogLoading();  
  31.                 break;  
  32.             }  
  33.   
  34.           
  35.             default:  
  36.                 break;  
  37.             }  
  38.         };  
  39.     };  
  40.   
  41.       
  42.     public void onCreate(Bundle savedInstanceState) {   
  43.         super.onCreate(savedInstanceState);   
  44.         setContentView(R.layout.insurance_list);   
  45.         initViews();  
  46.         getList();  
  47.     }   
  48.     
  49.     /** 
  50.      * 初始化view 
  51.      */  
  52.     private void initViews(){  
  53.           
  54.         mListView = (ListView)findViewById(R.id.list);  
  55.         mListView.setAdapter(mAdapter);  
  56.         mListView.setOnItemClickListener(new OnItemClickListener(){  
  57.             public void onItemClick(AdapterView<?> arg0, View v, int id,  
  58.                     long pos) {  
  59.                 // 获得被单击的项       
  60.                 //跳转  
  61.               
  62.             }  
  63.         });  
  64.      
  65.           
  66.         mListItems = new ArrayList<data>();  
  67.   
  68.     }  
  69.   
  70.       
  71.     
  72.     private void getList() {  
  73.         showDialogLoading();  
  74.          //得到保险列表  
  75.         insuranceData insurance = new insuranceData();  
  76.         insList = insurance.getList();  
  77.         mListItems.clear();  
  78.         mListItems.addAll(insList);  
  79.         mHandler.sendEmptyMessage(REFRESH_LIST);  
  80.           
  81.           
  82.     }  
  83.       
  84.   
  85.     private ProgressDialog mLoadingDialog;  
  86.   
  87.     private void showDialogLoading() {  
  88.         mLoadingDialog = new ProgressDialog(this);                   
  89.         mLoadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);  
  90.          //spinner  自旋体 像螺旋桨那样                               
  91.         mLoadingDialog.setMessage("载入中,请稍候...");                   
  92.         mLoadingDialog.setIndeterminate(false);//设置进度条是否为不明确                  
  93.         mLoadingDialog.setCancelable(true);//设置进度条是否可以按退回健取消                                 
  94.         mLoadingDialog.show();   
  95.     }  
  96.   
  97.     private void unShowDialogLoading() {  
  98.         if (mLoadingDialog == null)  
  99.             return;  
  100.         else  
  101.             mLoadingDialog.dismiss();  
  102.     }  
  103.       
  104. }  

 

它的Adapter是

 

Java代码   收藏代码
  1. public class InsuranceItemAdapter extends BaseAdapter{  
  2.     private ArrayList<data> mList;  
  3.     private Context mContext;  
  4.     // 异步加载图片的线程  
  5.     private AsyncImageLoader imageLoader = new AsyncImageLoader();  
  6.     //当前的缓存  
  7.     private Map<Integer, View> viewMap = new HashMap<Integer, View>();  
  8.   
  9.     public InsuranceItemAdapter(Context context, ArrayList<data> ins) {  
  10.         mContext = context;  
  11.         mList= ins;  
  12.     }  
  13.   
  14.     public InsuranceItemAdapter(Context context, ArrayList<data> ins,  
  15.             Handler handler) {  
  16.         mContext = context;  
  17.         mList= ins;  
  18.     }  
  19.   
  20.     public void setInsurance(ArrayList<data> ins) {  
  21.         mList= ins;  
  22.     }  
  23.       
  24.       
  25.       
  26.     public int getCount() {  
  27.         return mList.size();  
  28.     }  
  29.   
  30.     public Object getItem(int position) {  
  31.         try {  
  32.             return mList.get(position);  
  33.         } catch (Exception ex) {  
  34.             return null;  
  35.         }  
  36.     }  
  37.   
  38.     public long getItemId(int position) {  
  39.         return position;  
  40.     }  
  41.   
  42.       
  43.     private View newView() {  
  44.         ItemView view = new ItemView(mContext);  
  45.         return view;  
  46.     }  
  47.       
  48.       
  49.       
  50.     public View getView(int position, View convertView, ViewGroup parent) {  
  51.         //先从缓存里面读取  
  52.         ViewHolder holder = null;    
  53.         View view;    
  54.           
  55.          if (viewMap.get(position) == null) {    
  56.             view = newView();  
  57.             holder = new ViewHolder();    
  58.             holder.mTitle = (TextView)view.findViewById(R.id.ins_title);  
  59.             holder.mTime = (TextView)view.findViewById(R.id.ins_time);  
  60.             holder.mType = (TextView)view.findViewById(R.id.ins_from);  
  61.             holder.mPic = (ImageView)view.findViewById(R.id.ins_small_pic);  
  62.             final int p = position;    
  63.             viewMap.put(position, view);    
  64.             view.setTag(holder);    
  65.          }else{  
  66.              Log.e("MainActivity","position2 = "+position);    
  67.              view = viewMap.get(position);    
  68.              holder = (ViewHolder)view.getTag();    
  69.          }  
  70.           
  71.          data ins = mList.get(position);  
  72.          holder.mTitle.setText(ins.getTitle());  
  73.   
  74.           
  75.         holder.mPic.setVisibility(View.VISIBLE);  
  76.           
  77.         // 异步加载图片  
  78.         Drawable cachedImage = imageLoader.loadDrawable(ins.getPic(), holder.mPic,  
  79.                 new ImageCallback() {  
  80.                     public void imageLoaded(Drawable imageDrawable,  
  81.                             ImageView imageView, String imageUrl) {  
  82.                         imageView.setImageDrawable(imageDrawable);  
  83.                     }  
  84.                 });  
  85.         if (cachedImage != null) {  
  86.             holder.mPic.setImageDrawable(cachedImage);  
  87.         }  
  88.            
  89.          return view;    
  90.   
  91.     }  
  92.       
  93.       
  94.     static class ViewHolder{    
  95.         ImageView mPic;  
  96.         TextView mTitle;  
  97.         TextView mTime;  
  98.         TextView mType;  
  99.     }  
  100. }  

 

 

原理简单,不罗嗦了

 

本地缓存

  

   就是先读取本地的数据,如果本地没有再从网络上获取

 

WebView中很简单,

Java代码   收藏代码
  1. //优先缓存  
  2.         mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  

 就能实现了。

 

 

其他地方我们就得自己写一个异步图片下载了,

Java代码   收藏代码
  1. public class AsyncImageLoader {  
  2.   
  3.      //SoftReference是软引用,是为了更好的为了系统回收变量  
  4.     private static HashMap<String, SoftReference<Drawable>> imageCache;  
  5.       
  6.     static {  
  7.         imageCache = new HashMap<String, SoftReference<Drawable>>();  
  8.     }  
  9.       
  10.       
  11.     public AsyncImageLoader() {  
  12.           
  13.     }  
  14.     public Drawable loadDrawable(final String imageUrl,final ImageView imageView, final ImageCallback imageCallback){  
  15.         if (imageCache.containsKey(imageUrl)) {  
  16.             //从缓存中获取  
  17.             SoftReference<Drawable> softReference = imageCache.get(imageUrl);  
  18.             Drawable drawable = softReference.get();  
  19.             if (drawable != null) {  
  20.                 return drawable;  
  21.             }  
  22.         }  
  23.         final Handler handler = new Handler() {  
  24.             public void handleMessage(Message message) {  
  25.                 imageCallback.imageLoaded((Drawable) message.obj, imageView,imageUrl);  
  26.             }  
  27.         };  
  28.         //建立新一个新的线程下载图片  
  29.         new Thread() {  
  30.             @Override  
  31.             public void run() {  
  32.                 Drawable drawable = null;  
  33.                 try {  
  34.                     drawable = ImageUtil.geRoundDrawableFromUrl(imageUrl, 20);  
  35.                 } catch (Exception e) {  
  36.                     e.printStackTrace();  
  37.                 }  
  38.                 imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));  
  39.                 Message message = handler.obtainMessage(0, drawable);  
  40.                 handler.sendMessage(message);  
  41.             }  
  42.         }.start();  
  43.         return null;  
  44.     }  
  45.     //回调接口  
  46.     public interface ImageCallback {  
  47.         public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl);  
  48.     }  
  49. }  

 

 

当然我们也可以存数据库中,从数据库中优先获取,当没有网络的时候达到离线阅读的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值