Android之ListView最佳化(使用Lrucache,圖片滑動時使用預設圖片,停止時載入)

來源:互聯網
上載者:User

注意:LruCache是有版本限制的,低版本的sdk需要在libs檔案夾添加相應的support-4v檔案。
本文改造的大部分是參考http://www.iteye.com/topic/1118828,感謝。
不廢話直接上工程代碼,內有關鍵注釋,項目就不上傳了,自己對照著上面網址改唄。

首先是Application檔案,負責建立圖片隱藏檔夾:

public class MyApp extends Application{    @Override    public void onCreate() {        super.onCreate();        File f = new File(Environment.getExternalStorageDirectory()+"/TestSyncListView/pic/");        if (!f.exists()) {            f.mkdirs();        }    }}

映像讀取工具類:

public class SyncImageLoaderUtil {private Object lock = new Object();        private boolean mAllowLoad = true;        private boolean firstLoad = true;        private int mStartLoadLimit = 0;        private int mStopLoadLimit = 0;        final Handler handler = new Handler();    //    private HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();        private LruCache<String,Bitmap> mMemoryCache;        RunInOtherThread runInOutherThread;        public SyncImageLoaderUtil(Context context) {          super();                  int memClass = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();        int cacheSize = 1024 * 1024 *memClass / 8;        mMemoryCache = new LruCache<String, Bitmap>(cacheSize){        @Override        protected int sizeOf(String key, Bitmap value) {        // TODO Auto-generated method stub        return value.getRowBytes();        }        };                runInOutherThread = new RunInOtherThread();          runInOutherThread.start();      }        public interface OnImageLoadListener {          public void onImageLoad(Integer t, Drawable drawable);            public void onError(Integer t);      }        public void setLoadLimit(int startLoadLimit, int stopLoadLimit) {          if (startLoadLimit > stopLoadLimit) {  //        LogUtil.i("test", startLoadLimit+"--錯誤---"+stopLoadLimit);            return;          }          mStartLoadLimit = startLoadLimit;          mStopLoadLimit = stopLoadLimit;      }        public void restore() {          mAllowLoad = true;          firstLoad = true;      }        public void lock() {          mAllowLoad = false;          firstLoad = false;      }        public void unlock() {          mAllowLoad = true;          synchronized (lock) {              lock.notifyAll();          }      }        public void loadImage(Integer t, String imageUrl,              OnImageLoadListener listener) {          final OnImageLoadListener mListener = listener;          final String mImageUrl = imageUrl;          final Integer mt = t;                    runInOutherThread.getHandler().post(new Runnable() {                @Override              public void run() {                  if (!mAllowLoad) {                      synchronized (lock) {                          try {                              lock.wait();                          } catch (InterruptedException e) {                              // TODO Auto-generated catch block                              e.printStackTrace();                          }                      }                  }                                    if (mAllowLoad && firstLoad) {                      loadImage(mImageUrl, mt, mListener);                  }    //                LogUtil.e("test", "原始開始:"+mStartLoadLimit+"原始當前位置:"+mt+"原始結束:"+mStopLoadLimit);                if (mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit) {  //                LogUtil.e("test", "開始:"+mStartLoadLimit+"當前位置:"+mt+"結束:"+mStopLoadLimit);                    loadImage(mImageUrl, mt, mListener);                }              }            });      }            private void loadImage(final String mImageUrl, final Integer mt,              final OnImageLoadListener mListener) {            if (mImageUrl!=null && mMemoryCache.get(mImageUrl)!=null) {  //            SoftReference<Drawable> softReference = imageCache.get(mImageUrl);              final Drawable d = new BitmapDrawable(mMemoryCache.get(mImageUrl));  //            LogUtil.d("ppp", "drawable:"+d);            if (d != null) {                  handler.post(new Runnable() {                      @Override                      public void run() {                          if (mAllowLoad) {                              mListener.onImageLoad(mt, d);                          }                      }                  });                  return;              }          }          try {              final Drawable d = loadImageFromUrl(mImageUrl);              if (d != null) {                  mMemoryCache.put(mImageUrl, ((BitmapDrawable)d).getBitmap());            }              handler.post(new Runnable() {                  @Override                  public void run() {                      if (mAllowLoad) {                          mListener.onImageLoad(mt, d);                      }                  }              });          } catch (IOException e) {              handler.post(new Runnable() {                  @Override                  public void run() {                      mListener.onError(mt);                  }              });              e.printStackTrace();          }      }        public static Drawable loadImageFromUrl(String url) throws IOException {          //DebugUtil.debug(url);          if (Environment.getExternalStorageState().equals(                  Environment.MEDIA_MOUNTED)) {              File f = new File(Environment.getExternalStorageDirectory()                      + "/Weiyu/pic/" + MD5Util.getMD5(url.getBytes()));              if (f.exists()) {                  FileInputStream fis = new FileInputStream(f);                  Drawable d = Drawable.createFromStream(fis, "src");                  return d;              }              URL m = new URL(url);              InputStream i = (InputStream) m.getContent();              DataInputStream in = new DataInputStream(i);              FileOutputStream out = new FileOutputStream(f);              byte[] buffer = new byte[1024];              int byteread = 0;              while ((byteread = in.read(buffer)) != -1) {                  out.write(buffer, 0, byteread);              }                         in.close();              out.close();             return loadImageFromUrl(url);          } else {              URL m = new URL(url);              InputStream i = (InputStream) m.getContent();              Drawable d = Drawable.createFromStream(i, "src");              return d;          }        }  }

  
線程輔助類:

public class RunInOtherThread {private static final String LOG_TAG = "RunInOtherThread";          private LooperThread localThread = new LooperThread();            private boolean isRunning = true;        public Handler getHandler(){          return localThread.getHandler();      }            private class LooperThread extends Thread {          private Handler mHandler;            public void run() {              Looper.prepare();              mHandler = new Handler() {                  public void handleMessage(Message msg) {                      onReceiveMessage(msg.what);                  }              };              Looper.loop();          }                    Handler getHandler(){              return mHandler;          }           }            public void start(){          localThread.start();      }            public void quit(){          localThread.getHandler().getLooper().quit();      }            public void sendMessage(int what){          getHandler().sendEmptyMessage(what);      }            public Thread getThread(){          return localThread;      }            public void onReceiveMessage(int what){};}

  
使用類:

// 執行個體化工具類SyncImageLoaderUtil syncImageLoader = new SyncImageLoaderUtil(mContext);syncImageLoader.loadImage(position, model.mPic, imageLoadListener);//應用介面:參數一是載入圖片的位置;參數二是載入的ImageView;參數三是回調介面// map儲存的鍵是位置,值是listview對應位置的布局HashMap map = new HashMap();map.put(position, convertView);SyncImageLoaderUtil.OnImageLoadListener imageLoadListener = new SyncImageLoaderUtil.OnImageLoadListener() {@Overridepublic void onImageLoad(Integer t, Drawable drawable) {View view = (View) map.get(t);if (view != null) {ImageView iv = (ImageView) view.findViewById(R.id.image);iv.setBackgroundDrawable(drawable);}}@Overridepublic void onError(Integer t) {                        // 圖片載入失敗                       // 取得listview對應的位置的行的內容布局                  MusicModel model = (MusicModel) getItem(t);View view = mListView.findViewWithTag(model);if (view != null) {ImageView iv = (ImageView) view.findViewById(R.id.image);iv.setBackgroundResource(R.drawable.img_pic);}}};// 實作類別而且需要實現OnScrollListener介面public void loadImage() {                // 不要在這裡使用listview的getFirstVisiblePosition方法,位置不準if (end >= getCount()) {end = getCount() - 1;}syncImageLoader.setLoadLimit(start, end);syncImageLoader.unlock();}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {// TODO Auto-generated method stubif (lodingView) {switch (scrollState) {case AbsListView.OnScrollListener.SCROLL_STATE_FLING:syncImageLoader.lock();break;case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:loadImage();break;case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:syncImageLoader.lock();break;default:break;}}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// 在這裡取得的位置較準確,不過也會出現特殊的奇疤機型是不行的                // start與end是定義的變數start = firstVisibleItem;end = firstVisibleItem + visibleItemCount;if (firstVisibleItem != 0) {                        // lodingView是控制變數,用來控制第一次進來視圖載入讀取圖片lodingView = true;} else {lodingView = false;loadImage();}}                
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.