浅谈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-->