一步一步实现ListView加载网络数据,下滑底部加载,顶部下拉刷新。并配有双缓存

来源:互联网 发布:淘宝客推广流程 编辑:程序博客网 时间:2024/04/18 20:15

随便扯扯1,我比较喜欢把判断写成 常量在前,变量在后的形式,主要是由于这样可以规避粗心引起的错误。

例如  0 == mLength ,可以规避不小心写成mLength = 0;因为书写成 0= mLength会报错,而mLength = 0 不会报错。

若引起阅读不便,请包涵。

今天我们计划要实现一个装满数据的ListView,并且在顶部下拉可以刷新,下滑到底部可以加载更多。分析需求,第一件事就是要将ListView装满数据,那么这个数据从哪里来?从网络来,所以第一件事就是将网络数据下载下来。因此先添加权限:

<uses-permission android:name="android.permission.INTERNET"/>
<!-- 硬盘缓存--><!-- 在SDCard中创建与删除文件权限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><!-- 往SDCard写入数据权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- 从SDCard读取数据权限 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

把后面三个也一起添加了吧,因为本例最终的效果要实现双缓存,所以对SD的读写权限也是必须的。
然后进入正题:加载网络数据:
package com.example.asynctaskdemo;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.TextView;import android.widget.Toast;import com.example.asynctaskdemo.NewsAdapter.IRefereshListener;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.net.MalformedURLException;import java.net.URL;import java.util.ArrayList;import java.util.List;public class MainActivity extends Activity {   private final static String TAG = "zxt/MainActivity";   private final String Url = "http://www.imooc.com/api/teacher?type=4&num=30";   List<NewsBean> mNewsDatas = null;      private RefreshListView mListView ;   private TextView mNoDatas;      //下拉数据刷新 改写数组为集合   //public static String[] urls;   public static List<String> urls;      //下拉数据刷新   private NewsAdapter mNewsAdapter;   //   @Override   protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.activity_main);      mListView = (RefreshListView) findViewById(R.id.listView1);      mNoDatas  =  (TextView) findViewById(R.id.tv_nodatas);      new NewTask().execute(Url);   }      //下拉刷新数据/* public interface IRefreshCompleteListener{      public void onRefreshComplete();   }   private IRefreshCompleteListener mRefreshComplete;   public void IRefreshCompleteListener(IRefreshCompleteListener listener){      mRefreshComplete = listener;   }*/   public void refreshData(RefreshListView listview){      //获取最新数据      setReflashData();      //֪ͨ������ʾ      //mRefreshComplete.onRefreshComplete();         }   //下拉刷新   private int newDataslength ;   private void setReflashData() {      new DownPullTask().execute(Url);      //执行更新 start      /*NewsBean bean = new NewsBean();      bean.NewsNo = "31";      bean.NewsName = "new Name";      bean.NewsDescription = "new Des";      bean.NewsPicResUrl = Math.random()>0.5? "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png" :         "http://img.my.csdn.net/uploads/201407/26/1406383291_6518.jpg";*/      //执行更新 end   }      private void showList(List<NewsBean> apk_list) {      //NewsAdapter adapter = (NewsAdapter) mListView.getAdapter();      /*if (adapter == null) {         listview = (ReFlashListView) findViewById(R.id.listview);         listview.setInterface(this);         adapter = new MyAdapter(this, apk_list);         listview.setAdapter(adapter);      } else {*/      if(mNewsAdapter!=null)         mNewsAdapter.onDateChange(apk_list);      //}   }   private class DownPullTask extends AsyncTask<String,Void,List<NewsBean>>{      @Override      protected List<NewsBean> doInBackground(String... params) {         Log.i(TAG,"NewTask:doInBackground");         return getDataByUrl(params[0]);      }      @Override      protected void onPostExecute(List<NewsBean> newsBeens) {         super.onPostExecute(newsBeens);         //fix bug if first nodata         //更新了几条数据         if(null!=newsBeens){            newDataslength = newsBeens.size();            if(null==mNewsDatas ){               mNewsDatas = new ArrayList<NewsBean>();            }            mNewsDatas.addAll(0,newsBeens);            showList(mNewsDatas);            //֪ͨlistview ˢ�������ϣ         }else{            newDataslength = 0;         }         mNewsAdapter.refreshComplete(newDataslength);         setHintVisibility(newsBeens);         Log.i(TAG,"NewTask:onPostExecute:"+newDataslength);         Toast.makeText(MainActivity.this,"成功更新"+newDataslength+"条新闻",Toast.LENGTH_SHORT).show();      }   }   //下拉刷新 end         class NewTask extends AsyncTask<String, Void, List<NewsBean>> {      @Override      protected List<NewsBean> doInBackground(String... params) {         return getDataByUrl(params[0]);      }      @Override      protected void onPostExecute(List<NewsBean> result) {         super.onPostExecute(result);         //下拉刷新         mNewsAdapter= new NewsAdapter(MainActivity.this, result,mListView);         //下拉刷新         mListView.setAdapter(mNewsAdapter);         mListView.setOnScrollListener(mNewsAdapter);         // 处理下拉刷新         mListView.setOnTouchListener(mNewsAdapter);         mNewsDatas = result;         // 处理下拉刷新                  //刷新回调         mNewsAdapter.setIRefereshListener(new IRefereshListener() {            @Override            public void onRefresh() {               mListView.postDelayed(new Runnable() {                                    @Override                  public void run() {                     refreshData(mListView);                  }               }, 1000);                           }         });         //刷新回调         setHintVisibility(result);         //加载更多begin         mNewsAdapter.setIOnScrollBottomListener(new NewsAdapter.IOnScrollBottomListener() {            @Override            public void onScrollBottom() {               mListView.postDelayed(new Runnable() {                  @Override                  public void run() {                     //加载数据                     loadMoreData();                     mNewsAdapter.bottomDataLoadComplete();                  }               }, 3000);            }         });         //加载更多end      }               }   //加载更多begin   private int index =100;   private void loadMoreData(){      NewsBean bean = new NewsBean();      bean.NewsNo = ""+index++;      bean.NewsPicResUrl = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";      /*List<NewsBean> datas = mNewsAdapter.getDatas();      datas.add(-1,bean);*/      mNewsAdapter.setData(-1,bean);      mNewsAdapter.notifyDataSetChanged();   }   //加载更多end   private void setHintVisibility(List<NewsBean> result) {      mNoDatas.setVisibility(result==null? View.VISIBLE:View.GONE);   }   public List<NewsBean> getDataByUrl(String url) {      List<NewsBean> datas = null;      try {         String jsonString = readStream(new URL(url).openStream());                  datas = parseJson(jsonString);         //Log.i("zxt", "jsonString:"+jsonString);      } catch (MalformedURLException e) {         // TODO Auto-generated catch block         e.printStackTrace();      } catch (IOException e) {         e.printStackTrace();      }      return datas;   }   private List<NewsBean> parseJson(String jsonString) {      try {                  JSONObject jsonObject = new JSONObject(jsonString);         JSONArray jsonArray = jsonObject.getJSONArray("data");         JSONObject data = null;         List<NewsBean> datas =  new ArrayList<NewsBean>();         NewsBean bean = null;         //处理下拉刷新加入         if(null==urls){            urls = new ArrayList<String>();         }         List<String> tempUrls = new ArrayList<String>();         //处理下拉刷新加入         for (int i = 0; i < jsonArray.length(); i++) {            data = (JSONObject) jsonArray.get(i);            bean = new NewsBean();            bean.NewsPicResUrl = data.getString("picSmall");            //处理下拉刷新加入            tempUrls.add(bean.NewsPicResUrl);            //处理下拉刷新加入            bean.NewsName = data.getString("name");            bean.NewsDescription = data.getString("description");            bean.NewsNo = data.getString("id");            //加载大图加入            bean.NewsPicBigResUrl = data.getString("picBig");            //加载大图加入            datas.add(bean);         }         //处理下拉刷新加入  将新的url 加入到最上方         urls.addAll(0,tempUrls);         //处理下拉刷新加入         return datas;      } catch (JSONException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }            return null;   }   private String readStream(InputStream is) {      StringBuilder jsonString = new StringBuilder();      try {         String line = "";         InputStreamReader isr = new InputStreamReader(is, "utf-8");         BufferedReader br = new BufferedReader(isr);         if (null != (line = br.readLine())) {            jsonString.append(line);         }      } catch (UnsupportedEncodingException e) {         // TODO Auto-generated catch block         e.printStackTrace();      } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }      return jsonString.toString();   }}
package com.example.asynctaskdemo;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.ValueAnimator;import android.animation.ValueAnimator.AnimatorUpdateListener;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnTouchListener;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;import java.util.List;public class NewsAdapter extends BaseAdapter implements OnScrollListener,        OnTouchListener {    private static final String TAG = "zxt/NewsAdapter";    private volatile List<NewsBean> mDatas;    private LayoutInflater mInflater;    private RefreshListView mListView;    private Context mContext;    // 网络图片加载    public List<NewsBean> getDatas() {        return mDatas;    }    public void setDatas(List<NewsBean> mDatas) {        this.mDatas = mDatas;    }    public void setData(int pos, NewsBean bean) {        if (-1 != pos) {            mDatas.add(pos, bean);            MainActivity.urls.add(pos, bean.NewsPicResUrl);        } else {            mDatas.add(bean);            MainActivity.urls.add(bean.NewsPicResUrl);        }    }    private ImageLoader mImageLoader;    public NewsAdapter(Context context, List<NewsBean> mDatas, RefreshListView listView) {        super();        mContext = context;        this.mDatas = mDatas;        this.mInflater = LayoutInflater.from(context);        //抽象成单例后改写 begin        //mImageLoader = new ImageLoader(listView);        mImageLoader = ImageLoader.getInstance(context);        mImageLoader.setmListView(listView);        //抽象成单例后改写 end        mListView = listView;        initHeaderView();        initFooterView();    }    private void initFooterView() {        mFooterView = mListView.getFooterView();    }    //下拉刷新数据    public void onDateChange(List<NewsBean> mDatas) {        this.mDatas = mDatas;        this.notifyDataSetChanged();    }    //下拉刷新数据    private void initHeaderView() {        headerView = mListView.findViewById(R.id.headerview);        // 获取View高度        headerHeight = mListView.getHeaderHeight();        mTipView = (TextView) headerView.findViewById(R.id.tip);        mTimeView = (TextView) headerView.findViewById(R.id.lastupdate_time);        mArrowView = (ImageView) headerView.findViewById(R.id.arrow);        mBar = (ProgressBar) headerView.findViewById(R.id.progress);    }    @Override    public int getCount() {        if (mDatas != null)            return mDatas.size();        return 0;    }    @Override    public Object getItem(int position) {        // TODO Auto-generated method stub        return mDatas.get(position);    }    @Override    public long getItemId(int position) {        // TODO Auto-generated method stub        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;        if (convertView == null) {            //Log.i(TAG, "getView->缓存为空:" + position);            holder = new ViewHolder();            convertView = mInflater.inflate(R.layout.item, parent, false);            holder.pic = (ImageView) convertView.findViewById(R.id.iv_pic);            holder.no = (TextView) convertView.findViewById(R.id.tv_no);            holder.name = (TextView) convertView.findViewById(R.id.tv_name);            holder.description = (TextView) convertView                    .findViewById(R.id.tv_description);            convertView.setTag(holder);        } else {            //Log.i(TAG, "getView->缓存过:" + position);            holder = (ViewHolder) convertView.getTag();        }        NewsBean bean = mDatas.get(position);        // 加载网络图片        holder.pic.setTag(bean.NewsPicResUrl);        // mImageLoader.getImageByAsyncTask(holder.pic, bean.NewsPicResUrl);        holder.pic.setImageResource(R.drawable.ic_launcher);        // 滑动优化 如果有缓存,则加载 否则不加载        final Bitmap pBitmap = mImageLoader.setDefaultBitmap(holder.pic, bean.NewsPicResUrl);        // /滑动优化        holder.name.setText(bean.NewsName);        holder.description.setText(bean.NewsDescription);        holder.no.setText(bean.NewsNo);        //添加事件点击 2015 12 24        final String urlBig = bean.NewsPicBigResUrl;        final String urlSmall = bean.NewsPicResUrl;        holder.pic.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(v.getContext(), "bean.NewsNo:" + urlBig, Toast.LENGTH_SHORT).show();                Intent intent = new Intent(mContext, BigImageActivity.class);                intent.putExtra("urlBig", urlBig);                intent.putExtra("urlSmall", urlSmall);                mContext.startActivity(intent);            }        });        //        return convertView;    }    class ViewHolder {        public ImageView pic;        public TextView name;        public TextView description;        public TextView no;    }    // 滚动时的优化 begin    private int mStart, mEnd;    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        if (scrollState == SCROLL_STATE_IDLE) {            Log.i(TAG, "scrollState:" + mStart + "-" + mEnd);            loadImages();        } else {            Log.i(TAG, "scrollState cancel:");            mImageLoader.cancelAllTasks();        }    }    private void loadImages() {        if (null != mDatas && mDatas.size() > 0) {            //修复bug 滑动时边缘不加载 begin            int start = mStart != 0 ? mStart - 1 : 0;            int end = mEnd != mDatas.size() ? mEnd + 1 : mEnd;            //修复bug 滑动时边缘不加载 end            mImageLoader.loadImages(start, end);        }    }    private boolean isInit = true;    //加载更多 begin    private boolean isLoading = false;    private View mFooterView;    public interface IOnScrollBottomListener {        void onScrollBottom();    }    private IOnScrollBottomListener mIOnScrollBottomListener;    public void setIOnScrollBottomListener(IOnScrollBottomListener onScrollBottomListener) {        mIOnScrollBottomListener = onScrollBottomListener;    }    public void bottomDataLoadComplete() {        //隐藏view 加载数据 改变flag        mFooterView.setVisibility(View.GONE);        isLoading = false;    }    //加载更多 end    @Override    public void onScroll(AbsListView view, int firstVisibleItem,                         int visibleItemCount, int totalItemCount) {        Log.i(TAG, "onScroll():totalItemCount" + totalItemCount + "  ,isLoading:" + isLoading + ",   firstVisibleItem:"                + firstVisibleItem + "  ,visibleItemCount:" + visibleItemCount + ", totalItemCount:" + totalItemCount);        mStart = firstVisibleItem;        //其实现在的listview看不到那么多 应该-1 否则最后会空指针 2015 12 24 (因为我们add了一个headerview进去)  20151228 add 了 footview 所以再-1        mEnd = mStart + visibleItemCount - 1 - 1;        if (visibleItemCount != 0 && isInit) {            isInit = false;            loadImages();        }        //处理滑动加载更多: 2 != totalItemCount 防止没有数据一直在加载更多        if (2 != totalItemCount && firstVisibleItem + visibleItemCount == totalItemCount && !isLoading) {            isLoading = true;            mFooterView.setVisibility(View.VISIBLE);            //执行加载更多操作            if (null != mIOnScrollBottomListener) {                mIOnScrollBottomListener.onScrollBottom();            }        }    }    // 滚动时的优化 end    // 处理下拉刷新    private int lastY;    private View headerView;    private TextView mTipView;    private TextView mTimeView;    private ImageView mArrowView;    private ProgressBar mBar;    private int headerHeight;    private int gap;    public interface IRefereshListener {        public void onRefresh();    }    private IRefereshListener mRefereshListener;    public void setIRefereshListener(IRefereshListener listener) {        this.mRefereshListener = listener;    }    //监听执行完毕 继续滚动    public void refreshComplete(int length) {        Log.i(TAG, "refreshComplete()");        //其实这里的mStarat =0的        mImageLoader.loadImages(mStart, mStart + length);        rollToInit(1);    }    @Override    public boolean onTouch(View v, MotionEvent event) {        if (mStart == 0 && isMoveEnable) {            switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    lastY = (int) event.getY();                    //初始化 几个view的状态显示                    mTipView.setText("下拉可以刷新");                    mArrowView.setVisibility(View.VISIBLE);                    mBar.setVisibility(View.GONE);                    //初始化 几个view的状态显示                    break;                case MotionEvent.ACTION_MOVE:                    gap = (int) (event.getY() - lastY);                    Log.i(TAG, " ACTION_MOVE gap:" + gap);                    //移动View                    setPaddingTop(-headerHeight + gap);                    //下拉可以刷新(超过宽度)-》松开可以刷新-》                    if (gap > headerHeight) {                        mTipView.setText("松开可以刷新");                    }                    //下拉可以刷新(超过宽度)-》松开可以刷新-》                    break;                case MotionEvent.ACTION_UP:                    //松开-》滑动到View宽度-》                    if (gap > headerHeight) {                        rollToInit(0);                        //正在刷新-》                        mTipView.setText("正在刷新");                        mArrowView.setVisibility(View.GONE);                        mBar.setVisibility(View.VISIBLE);                        //执行刷新操作                        if (mRefereshListener != null) {                            mRefereshListener.onRefresh();                        }                        //执行刷新操作                        //松开-》滑动到View宽度-》                    } else {                        //恢复初始。                        rollToInit(1);                    }                    break;                default:                    break;            }            Log.i(TAG, "lastY:" + lastY + "headerHeight:" + headerHeight);        }        return false;    }    private boolean isMoveEnable = true;    private void rollToInit(int endTop) {        //回去的动画://使用ObjectAnimator 不好实现, 打算用ValueAnimator        /*ObjectAnimator animator = ObjectAnimator.ofFloat(mListView, "Y",-(headerView.getPaddingTop()+headerHeight));      animator.setDuration(500).start();*/        isMoveEnable = false;        int top = headerView.getPaddingTop();        //解决 拖动不超过headerheight 不会滑动回去的bug        int end = top > 0 ? -(top + headerHeight) : -(top + headerHeight + headerHeight);        Log.i(TAG, "rollToInit:" + endTop + "  ,top:" + top + ", -(top+headerHeight)  " + (-(top + headerHeight)));        ValueAnimator animator = ValueAnimator.ofInt(top, endTop == 1 ? end : endTop);        animator.addUpdateListener(new AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                Integer paddingTop = (Integer) animation.getAnimatedValue();                setPaddingTop(paddingTop);            }        });        //添加动画完成监听器        animator.addListener(new AnimatorListenerAdapter() {            @Override            public void onAnimationEnd(Animator animation) {                super.onAnimationEnd(animation);                isMoveEnable = true;            }        });        //添加动画完成监听器        animator.setDuration(500).start();    }    private void setPaddingTop(int top) {        if (null != headerView) {            headerView.setPadding(headerView.getPaddingLeft(), top, headerView.getPaddingRight(), headerView.getPaddingBottom());        }    }}

package com.example.asynctaskdemo;public class NewsBean {   public String NewsPicResUrl;   public String NewsPicBigResUrl;   public String NewsName;   public String NewsDescription;   public String NewsNo;}

package com.example.asynctaskdemo;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;public class RefreshListView extends android.widget.ListView {   private final static String TAG ="zxt/refreshListView";   private View headerView ;   private View footerView;   public View getFooterView() {      return footerView;   }   /*public void bottomDataLoadComplete(){      //隐藏view 加载数据 改变flag      footerView.setVisibility(View.GONE);   }*/   private int headerHeight;   public int getHeaderHeight() {      return headerHeight;   }   public RefreshListView(Context context) {      this(context, null);   }   public RefreshListView(Context context, AttributeSet attrs) {      this(context, attrs, 0);   }   public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {      super(context, attrs, defStyleAttr);      initView(context);         }   private void initView(Context context) {      headerView = LayoutInflater.from(context).inflate(R.layout.header,null);      this.addHeaderView(headerView);      // 测量View      headerView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);      // 获取View高度      headerHeight = headerView.getMeasuredHeight();      Log.d(TAG, "headerHeight:"+headerHeight);      //设置默认隐藏      setPaddingTop(-headerHeight);      //上啦刷新      View footerView = LayoutInflater.from(context).inflate(R.layout.footer_layout,this,false);      this.addFooterView(footerView);      this.footerView = footerView.findViewById(R.id.load_layout);      this.footerView.setVisibility(View.GONE);   }         private void setPaddingTop(int top){      if(null!=headerView){         headerView.setPadding(headerView.getPaddingLeft(), top, headerView.getPaddingRight(), headerView.getPaddingBottom());      }   }}

package com.example.asynctaskdemo;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.support.annotation.Nullable;import android.support.v4.util.LruCache;import android.util.Log;import android.view.View;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import com.example.asynctaskdemo.com.mcxtzhang.utils.FileUtils;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileDescriptor;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.HashSet;import java.util.Set;import libcore.io.DiskLruCache;public class ImageLoader {   private static final String TAG = "zxt/ImageLoader";   //抽象成单例 begin   private static class ImageLoaderHolder {      private static final ImageLoader mImageLoader = new ImageLoader();   }   private static Context mContext;   public static ImageLoader getInstance(Context context){      mContext = context.getApplicationContext();      return ImageLoaderHolder.mImageLoader;   }   private ImageLoader() {      super();      Log.i("TAG","ImageLoader");      int maxMemory = (int) Runtime.getRuntime().maxMemory();      mCache = new LruCache<String, Bitmap>(maxMemory / 20) {         @Override         protected int sizeOf(String key, Bitmap value) {            return value.getByteCount();         }      };      //硬盘缓存 begin      //初始化工作      File cacheDir = FileUtils.getFileCache(mContext, "disk_caches");      if (!cacheDir.exists()) {         cacheDir.mkdirs();      }      try {         mDiskCache = DiskLruCache.open(cacheDir, 1, 1, 10 * 1024 * 1024);      } catch (IOException e) {         e.printStackTrace();      }      //硬盘缓存 end      mSets = new HashSet<NewsImageAsyncTask>();   }   //抽象成单例 end   //图片缓存 start   private LruCache<String,Bitmap> mCache;   //硬盘缓存   private DiskLruCache mDiskCache;   public Bitmap getBitmapFromCache(String url){      Log.i(TAG, "getBitmapFromCache");      return mCache.get(url);   }   public void putBitmapToCache(String url,Bitmap bitmap){      Log.i(TAG, "putBitmapToCache");      if(null == getBitmapFromCache(url)){         mCache.put(url, bitmap);      }   }   //图片缓存 end    public void getImageByAsyncTask(ImageView imageView,String url){      //图片缓存 start      Bitmap bitmap = getBitmapFromCache(url);      if(null == bitmap)      {              new NewsImageAsyncTask(/*imageView,*/url).execute();      }      else{         imageView.setImageBitmap(bitmap);      }      //图片缓存 end   }      //每次加载一张图片   private class NewsImageAsyncTask extends AsyncTask<Void,Void,Bitmap>{      //private ImageView mImageView ;      private String mUrl;      public NewsImageAsyncTask(/*ImageView mImageView,*/String url) {         super();         //this.mImageView = mImageView;         mUrl = url;      }      @Override      protected Bitmap doInBackground(Void... params) {         //硬盘缓存         // 用了二级缓存 所以要改写获取图片的流程:         /*Bitmap result = getBitmapByUrl(mUrl);         Log.i(TAG, "isCancelled:"+isCancelled());         //内存缓存 start         putBitmapToCache(mUrl, result);         //内存缓存end*/         return getBitmapAndSaveToCacheByUrl(mUrl);      }      @Override      protected void onPostExecute(Bitmap result) {         super.onPostExecute(result);         //设置图片 防止错位         /*if(mUrl.equals(mImageView.getTag())){            mImageView.setImageBitmap(result);         }*/         //滑动优化         ImageView imageView = (ImageView) mListView.findViewWithTag(mUrl);         if(imageView!=null && null != result)         {            imageView.setImageBitmap(result);         }                  mSets.remove(this);         //滑动优化                                 }                     }   public Bitmap getBitmapByUrl(String string) {      InputStream is1=null/*,is2 = null*/;      Bitmap result = null;      try {         HttpURLConnection conn = (HttpURLConnection) new URL(string).openConnection();         is1 = new BufferedInputStream(conn.getInputStream());         //优化图片加载 begin         /*ByteArrayOutputStream out = new ByteArrayOutputStream();         ImageUtils.copy(is1,out);         is2 = new ByteArrayInputStream(out.toByteArray());*/         result = BitmapFactory.decodeStream(is1);         //result  = ImageUtils.decodeSuitableBitmap(is,60,60);         //result = ImageUtils.decodeSuitableBitmap(string,1,1);         //Log.i(TAG,"resutl size:"+result.getByteCount());         //result = ImageUtils.decodeSampledBitmapFromInputStream(is1,is2,1,1);         Log.i(TAG,"resutl size:"+(result !=null?result.getByteCount():"null"));         /*if (result==null){            Log.i(TAG,"result==null");         }*/         //Log.i(TAG,"result="+result);         //优化图片加载 end         conn.disconnect();      } catch (MalformedURLException e) {         // TODO Auto-generated catch block         e.printStackTrace();      } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();      }finally{         try {            if(is1!=null){               is1.close();            }            /*if(is2!=null){               is2.close();            }*/         } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();         }      }      return result;   }   //滚动时的优化 begin   private static Set<NewsImageAsyncTask> mSets ;   private ListView mListView;   public ListView getmListView() {      return mListView;   }   public void setmListView(ListView mListView) {      this.mListView = mListView;   }   public void loadImages(int mStart, int mEnd) {      Log.i(TAG, "loadImages:" + mStart+"-"+mEnd);      for (int i = mStart; i < mEnd; i++) {         Log.i(TAG, "loadImages:"+i);         String url = MainActivity.urls.get(i);         Bitmap bm = getBitmapFromCache(url);         ImageView mImageView = (ImageView)mListView.findViewWithTag(url);         if(null!=bm && null!= mImageView){                        mImageView.setImageBitmap(bm);         }         else{//重新下载            NewsImageAsyncTask task = new NewsImageAsyncTask(url);            mSets.add(task);            task.execute();         }      }   }      public void cancelAllTasks() {      if(mSets!=null){         for (NewsImageAsyncTask task : mSets) {            task.cancel(false);         }      }   }      //看缓存中是否有 有则设置 没有则默认图片不管   public Bitmap setDefaultBitmap(ImageView pic, String newsPicResUrl) {      Bitmap bm = getBitmapFromCache(newsPicResUrl);      if(null!=bm){         pic.setImageBitmap(bm);      }      return bm;   }      //滚动时的优化 end      //硬盘缓存 加载图片方法(不返回bitmap,为了通用,不仅仅保存图片) 并写入硬缓存 begin   private static boolean getBitmapUrlToStream(String urlString, OutputStream outputStream) {      HttpURLConnection urlConnection = null;      BufferedOutputStream out = null;      BufferedInputStream in = null;      try {         final URL url = new URL(urlString);         urlConnection = (HttpURLConnection) url.openConnection();         in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);         out = new BufferedOutputStream(outputStream, 8 * 1024);         int b;         while ((b = in.read()) != -1) {            out.write(b);         }         return true;      } catch (final IOException e) {         e.printStackTrace();      } finally {         if (urlConnection != null) {            urlConnection.disconnect();         }         try {            if (out != null) {               out.close();            }            if (in != null) {               in.close();            }         } catch (final IOException e) {            e.printStackTrace();         }      }      return false;   }   //硬盘缓存 加载图片方法 end   //硬盘缓存  下载图片 存入缓存(SD ,内存都存入)方法 begin   @Nullable   private Bitmap getBitmapAndSaveToCacheByUrl(String mUrl) {      String key = FileUtils.toMD5String(mUrl);      FileDescriptor fileDescriptor = null;      FileInputStream fileInputStream = null;      DiskLruCache.Snapshot snapShot = null;      try {         //尝试获取硬缓存里的数据         snapShot = mDiskCache.get(key);         //如果没有缓存         if (snapShot == null) {            //尝试读从网络取并写入            DiskLruCache.Editor editor = mDiskCache.edit(key);            if (editor != null) {               OutputStream outputStream = editor.newOutputStream(0);               if (getBitmapUrlToStream(mUrl, outputStream)) {                  editor.commit();               } else {                  editor.abort();               }            }            //再次读取            snapShot = mDiskCache.get(key);         }         if (snapShot != null) {            fileInputStream = (FileInputStream) snapShot.getInputStream(0);            fileDescriptor = fileInputStream.getFD();         }         //利用读取的硬盘数据,生成bitmap         Bitmap bitmap = null;         if (fileDescriptor != null) {            bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);         }         //利用bitmap 存入内存缓存         if (bitmap != null) {            putBitmapToCache(mUrl, bitmap);         }         //返回bitmap         return bitmap;      } catch (IOException e) {         e.printStackTrace();      } finally {         if (fileDescriptor == null && fileInputStream != null) {            try {               fileInputStream.close();            } catch (IOException e) {            }         }      }      return null;   }   //end   //加载大图   public void loadBigBitmap(String url, ImageView imageView, ProgressBar mProgressBar){      if(imageView!=null && null!= url){         new BigImageAsyncTask(imageView,mProgressBar).execute(url);      }   }   private class BigImageAsyncTask extends AsyncTask<String,Void,Bitmap> {      private ImageView mImageView;      private ProgressBar mProgressBar;      public BigImageAsyncTask(ImageView imageView, ProgressBar progressBar) {         mImageView = imageView;         mProgressBar = progressBar;      }      @Override      protected Bitmap doInBackground(String... params) {         return getBitmapByUrl(params[0]);      }      @Override      protected void onPostExecute(Bitmap bitmap) {         super.onPostExecute(bitmap);         if(bitmap!=null)            mImageView.setImageBitmap(bitmap);         if(null!=mProgressBar){            mProgressBar.setVisibility(View.GONE);         }      }   }}

package com.example.asynctaskdemo;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.util.Log;import android.widget.ImageView;import android.widget.ProgressBar;/** * Created by zhangxutong on 2015/12/25. */public class BigImageActivity extends Activity{    private ImageView mBigImageView;    private ProgressBar mProgressBar;    private ImageLoader mImageLoader;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_bigimage);        initView();        mImageLoader = ImageLoader.getInstance(BigImageActivity.this);        Intent intent = getIntent() ;        String urlBig = intent.getStringExtra("urlBig");        String urlSmall = intent.getStringExtra("urlSmall");        //设置初始值        if(null!=urlSmall) {            Bitmap bitmap = mImageLoader.getBitmapFromCache(urlSmall);            Log.i("TAG","urlSmall:"+urlSmall+", bitmap:"+bitmap);            if(null!=bitmap){                mBigImageView.setImageBitmap(bitmap);            }        }        //加载大图        mImageLoader.loadBigBitmap(urlBig,mBigImageView,mProgressBar);    }    private void initView() {        mBigImageView = (ImageView) findViewById(R.id.iv_bigimage);        mProgressBar = (ProgressBar) findViewById(R.id.pb);    }}

7 0
原创粉丝点击