Android新浪微部落格戶端(七)——ListView中的圖片非同步載入、緩衝

來源:互聯網
上載者:User

標籤:android   style   class   blog   c   code   

原文出自:方傑|http://fangjie.sinaapp.com/?p=193 轉載請註明出處

最終效果示範:http://fangjie.sinaapp.com/?page_id=54
該項目代碼已經放到github:https://github.com/JayFang1993/SinaWeibo

一.ListView的圖片非同步載入
我們都知道對每一個Weibo Item都有帳戶圖片,而且每一條微博還可能帶有圖片。如果在載入列表的同時載入圖片,這樣有幾個缺點,第一很費事,介面卡住,使用者體驗很不好,第二Android在主線程中不能有網路操作,所以本身實現起來就很麻煩。所以我們才實現一個圖片非同步載入類。繼承自AsyncTask<String, Void, Bitmap>,重載其中的方法。doInBackground才是真正的非同步作業,做一些耗時的任務,這裡就是去伺服器上下載圖片,onPostExecute是在doInBackground結束後調用的,並傳入doInBackground的傳回值。

    public AsyncImageLoader(ImageView image, LruCache<String, Bitmap> lruCache,int width,int height) {          super();          this.image = image;          this.lruCache = lruCache;          this.width=width;        this.height=width;    }      @Override      protected Bitmap doInBackground(String... params) {          Bitmap bitmap = null;          bitmap = GetUserInfo.getBitmap(params[0]);         if(width!=0&height!=0)            bitmap=GetUserInfo.scaleImg(bitmap, width, height);        addBitmapToMemoryCache(params[0], bitmap);          return bitmap;      }      @Override      protected void onPostExecute(Bitmap bitmap) {          image.setImageBitmap(bitmap);      }

然後在WeiboAdapter中封裝一個介面 loadBitmap,載入圖片。

二.ListView圖片緩衝

ListView經常會上下滑動,而這些圖片載入任務就會反覆調用,這樣就很浪費。可以為圖片實現緩衝,當某個圖片載入過之後需要再次顯示只需要從記憶體中拿出來顯示就可以,不需要再去載入。緩衝其實有兩種緩衝,一種是記憶體緩衝,另一種是SD卡緩衝,即下載圖片到SD卡中。這裡我們只講記憶體緩衝。

結合上面的圖片非同步載入,整個圖片顯示的過程是這樣:當需要顯示圖片的時候,先去記憶體中尋找看是否有這種圖片的緩衝,有的話就直接顯示,沒有的話,去非同步載入,然後儲存到記憶體緩衝中,然後顯示。

完整的AsyncImageLoader.java代碼

package com.fangjie.weibo.util;import android.graphics.Bitmap;import android.os.AsyncTask;import android.support.v4.util.LruCache;import android.widget.ImageView;public class AsyncImageLoader extends AsyncTask<String, Void, Bitmap> {    private ImageView image;      private LruCache<String, Bitmap> lruCache;      private int width;    private int height;    /**      * 構造方法,需要把ImageView控制項和LruCache 對象傳進來      * @param image 載入圖片到此 {@code}ImageView      * @param lruCache 緩衝圖片的對象      */      public AsyncImageLoader(ImageView image, LruCache<String, Bitmap> lruCache,int width,int height) {          super();          this.image = image;          this.lruCache = lruCache;          this.width=width;        this.height=width;    }      @Override      protected Bitmap doInBackground(String... params) {          Bitmap bitmap = null;          bitmap = GetUserInfo.getBitmap(params[0]);         if(width!=0&height!=0)            bitmap=GetUserInfo.scaleImg(bitmap, width, height);        addBitmapToMemoryCache(params[0], bitmap);          return bitmap;      }      @Override      protected void onPostExecute(Bitmap bitmap) {          image.setImageBitmap(bitmap);      }          //調用LruCache的put 方法將圖片加入記憶體緩衝中,要給這個圖片一個key 方便下次從緩衝中取出來      private void addBitmapToMemoryCache(String key, Bitmap bitmap) {          if (getBitmapFromMemoryCache(key) == null) {              lruCache.put(key, bitmap);          }      }          //調用Lrucache的get 方法從記憶體緩衝中去圖片      public Bitmap getBitmapFromMemoryCache(String key) {          return lruCache.get(key);      }  }

在WeiboAdapter中的調用介面,loadBitmap

    private final int maxMemory = (int) Runtime.getRuntime().maxMemory();//擷取當前應用程式所分配的最大記憶體      private final int cacheSize = maxMemory / 5;//只分5分之一用來做圖片緩衝      private LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>(              cacheSize) {           protected int sizeOf(String key, Bitmap bitmap) {//複寫sizeof()方法              // replaced by getByteCount() in API 12              return bitmap.getRowBytes() * bitmap.getHeight() / 1024; //這裡是按多少KB來算          }      };     /**     *      * @param urlStr 所需要載入的圖片的url,以String形式傳進來,可以把這個url作為緩衝圖片的key     * @param image ImageView 控制項     */    private void loadBitmap(String urlStr, ImageView image,int width,int height) {        System.out.println(urlStr);        AsyncImageLoader asyncLoader = new AsyncImageLoader(image, mLruCache,width,height);//什麼一個非同步圖片載入對象        Bitmap bitmap = asyncLoader.getBitmapFromMemoryCache(urlStr);//首先從記憶體緩衝中擷取圖片        if (bitmap != null) {            image.setImageBitmap(bitmap);//如果緩衝中存在這張圖片則直接設定給ImageView        } else {            image.setImageResource(R.drawable.user_head);//否則先設定成預設的圖片            asyncLoader.execute(urlStr);//然後執行非同步任務AsycnTask 去網上載入圖片        }    }

至此,微博首頁的微博列表載入也就全部完成。還有很多細小的點都沒講到,但是都有源碼,相信大家都能看得懂的。整個工程檔案:

代碼放在:http://git.oschina.net/fangjie/Sina-Weibo  效果展示:http://fangjie.sinaapp.com/?page_id=54

:由於新浪微博的開發平台申請的應用沒有通過審核,所以不是所有的微博帳號都可以授權成功,需要測試的話可以找我,也可以在源碼中(com.fangjie.weibo.util.AuthUtil)改成你申請的appkey,appsecret。

微部落格戶端項目有時間再往下寫吧!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.