ListView中的图片异步加载、缓存
一.ListView的圖片異步加載
我們都知道對每一個Weibo Item都有用戶頭像,而且每一條微博還可能帶有圖片。如果在加載列表的同時加載圖片,這樣有幾個缺點,第一很費事,界面卡住,用戶體驗很不好,第二Android在主線程中不能有網絡操作,所以本身實現起來就很麻煩。所以我們才實現一個圖片異步加載類。繼承自AsyncTask<String, Void, Bitmap>,重載其中的方法。doInBackground才是真正的異步操作,做一些耗時的任務,這里就是去服務器上下載圖片,onPostExecute是在doInBackground結束后調用的,并傳入doInBackground的返回值。
然后在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。
微博客戶端項目有時間再往下寫吧!
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的ListView中的图片异步加载、缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android在初始化时弹出popwin
- 下一篇: Home界面的ListView