浅谈Android ListView 异步图片获取

来源:互联网 发布:淘宝买iphone怎么验货 编辑:程序博客网 时间:2024/06/03 09:38

    浅谈Android ListView 异步图片获取

 

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

 

我们一般的处理方法是:

 

 

异步下载

 

本地缓存

 

 

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

先说异步下载



 

 

如一个ListView的异步下载

 

public class AsyncActivity extends Activity  {List<data> insList;private ListView mListView;private ArrayList<data> mListItems;private ItemAdapter mAdapter;private ImageView mLfteView;private ImageView mRightView;private static final int REFRESH_LIST = 1;Handler mHandler = new Handler() {public void handleMessage(android.os.Message msg) {int type = msg.what;switch (type) {case REFRESH_LIST: {if (mListItems.size() > 0) {mListView.setVisibility(View.VISIBLE);if (mAdapter== null) {mAdapter = new Adapter(AsyncActivity.this,mListItems);mListView.setAdapter(mAdapter);}mAdapter.notifyDataSetChanged();}mListView.requestFocus();unShowDialogLoading();break;}default:break;}};};    public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.insurance_list);         initViews();        getList();    }       /**     * 初始化view     */    private void initViews(){        mListView = (ListView)findViewById(R.id.list);    mListView.setAdapter(mAdapter);    mListView.setOnItemClickListener(new OnItemClickListener(){public void onItemClick(AdapterView<?> arg0, View v, int id,long pos) {    // 获得被单击的项             //跳转    }    });           mListItems = new ArrayList<data>();    }          private void getList() {    showDialogLoading();     //得到列表        Data ins = new Data();        insList = ins.getList();        mListItems.clear();        mListItems.addAll(insList);        mHandler.sendEmptyMessage(REFRESH_LIST);                    }        private ProgressDialog mLoadingDialog;private void showDialogLoading() {mLoadingDialog = new ProgressDialog(this);                 mLoadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); //spinner  自旋体 像螺旋桨那样                             mLoadingDialog.setMessage("载入中,请稍候...");                 mLoadingDialog.setIndeterminate(false);//设置进度条是否为不明确                mLoadingDialog.setCancelable(true);//设置进度条是否可以按退回健取消                               mLoadingDialog.show(); }private void unShowDialogLoading() {if (mLoadingDialog == null)return;elsemLoadingDialog.dismiss();}}

 

 

 

 它的Adapter是

 

public class ItemAdapter extends BaseAdapter{private ArrayList<data> mList;private Context mContext;// 异步加载图片的线程private AsyncImageLoader imageLoader = new AsyncImageLoader();//当前的缓存    private Map<Integer, View> viewMap = new HashMap<Integer, View>();public InsuranceItemAdapter(Context context, ArrayList<data> ins) {mContext = context;mList= ins;}public InsuranceItemAdapter(Context context, ArrayList<data> ins,Handler handler) {mContext = context;mList= ins;}public void setInsurance(ArrayList<data> ins) {mList= ins;}public int getCount() {return mList.size();}public Object getItem(int position) {try {return mList.get(position);} catch (Exception ex) {return null;}}public long getItemId(int position) {return position;}private View newView() {InsItemView insView = new InsItemView(mContext);return insView;}public View getView(int position, View convertView, ViewGroup parent) {//先从缓存里面读取ViewHolder holder = null;  View view;   if (viewMap.get(position) == null) {  view = newView();holder = new ViewHolder();  holder.mTitle = (TextView)view.findViewById(R.id.ins_title);holder.mTime = (TextView)view.findViewById(R.id.ins_time);holder.mType = (TextView)view.findViewById(R.id.ins_from);holder.mPic = (ImageView)view.findViewById(R.id.ins_small_pic);final int p = position;  viewMap.put(position, view);              view.setTag(holder);   }else{ Log.e("MainActivity","position2 = "+position);               view = viewMap.get(position);               holder = (ViewHolder)view.getTag();   } data ins = mList.get(position); holder.mTitle.setText(ins.getTitle());holder.mPic.setVisibility(View.VISIBLE);// 异步加载图片Drawable cachedImage = imageLoader.loadDrawable(ins.getPic(), holder.mPic,new ImageCallback() {public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl) {imageView.setImageDrawable(imageDrawable);}});if (cachedImage != null) {holder.mPic.setImageDrawable(cachedImage);}                  return view;  }static class ViewHolder{  ImageView mPic;TextView mTitle;TextView mTime;TextView mType;}}

 

 

 

 

 

 

  

原理简单,不罗嗦了

 

本地缓存

  

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

 

WebView中很简单,//优先缓存 mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

 

 

  就能实现了。

 

 

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

 

 

package cn.ethink.activity.net;import java.lang.ref.SoftReference;import java.util.HashMap;import android.graphics.drawable.Drawable;import android.os.Handler;import android.os.Message;import android.widget.ImageView;import cn.ethink.activity.view.utils.ImageUtil;public class AsyncImageLoader { //SoftReference是软引用,是为了更好的为了系统回收变量    private static HashMap<String, SoftReference<Drawable>> imageCache;        static {    imageCache = new HashMap<String, SoftReference<Drawable>>();    }            public AsyncImageLoader() {            }    public Drawable loadDrawable(final String imageUrl,final ImageView imageView, final ImageCallback imageCallback){        if (imageCache.containsKey(imageUrl)) {            //从缓存中获取            SoftReference<Drawable> softReference = imageCache.get(imageUrl);            Drawable drawable = softReference.get();            if (drawable != null) {                return drawable;            }        }        final Handler handler = new Handler() {            public void handleMessage(Message message) {                imageCallback.imageLoaded((Drawable) message.obj, imageView,imageUrl);            }        };        //建立新一个新的线程下载图片        new Thread() {            @Override            public void run() {                Drawable drawable = null;try {drawable = ImageUtil.geRoundDrawableFromUrl(imageUrl, 20);} catch (Exception e) {e.printStackTrace();}                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));                Message message = handler.obtainMessage(0, drawable);                handler.sendMessage(message);            }        }.start();        return null;    }    //回调接口    public interface ImageCallback {        public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl);    }}

 

 

 

 

 

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

 

 

 

<!--EndFragment-->