android ListView異步加載圖片
ListView異步加載圖片是非常實用的方法,凡是是要通過網(wǎng)絡(luò)獲取圖片資源一般使用這種方法比較好,用戶體驗好,不用讓用戶等待下去,下面就說實現(xiàn)方法,先貼上主方法的代碼
本文引用地址:http://www.biyoush.com/article/201609/305008.htmpublic class AsyncImageLoader {
private HashMap
public AsyncImageLoader() {
imageCache = new HashMap
}
public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
if (imageCache.containsKey(imageUrl)) {
SoftReference
Drawable drawable = softReference.get();
if (drawable != null) {
return drawable;
}
}
final Handler handler = new Handler() {
public void handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};
new Thread() {
@Override
public void run() {
Drawable drawable = loadImageFromUrl(imageUrl);
imageCache.put(imageUrl, new SoftReference
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}
}.start();
return null;
}
public static Drawable loadImageFromUrl(String url) {
URL m;
InputStream i = null;
try {
m = new URL(url);
i = (InputStream) m.getContent();
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Drawable d = Drawable.createFromStream(i, src);
return d;
}
public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}
}
實現(xiàn)方式:通過傳入圖片的網(wǎng)絡(luò)地址和一個實現(xiàn)ImageCallback行為的對象,當(dāng)imageCache存在這個圖片時候,返回這個圖片,當(dāng)imageCache沒有這個圖片時,實例一個異步線程來下載圖片并同時返回為null,最后在圖片下載完成的時候,調(diào)用imageLoaded方法。
現(xiàn)說說這個類設(shè)計的優(yōu)點吧:1.采用了策略模式;2.使用SoftReference關(guān)鍵字
先說說策略模式,程序里把每次下載圖片完成后所進行的操作封裝成一個ImageCallback抽象類,使系統(tǒng)更靈活,并易于擴展。
在Java中內(nèi)存管理,引用分為四大類,強引用HardReference、弱引用WeakReference、軟引用SoftReference和虛引用PhantomReference。它們的區(qū)別也很明顯,HardReference對象是即使虛擬機內(nèi)存吃緊拋出OOM也不會導(dǎo)致這一引用的對象被回收,而WeakReference等更適合于一些數(shù)量不多,但體積稍微龐大的對象,在這四個引用中,它是最容易被垃圾回收的,而我們對于顯示類似Android Market中每個應(yīng)用的App Icon時可以考慮使用SoftReference來解決內(nèi)存不至于快速回收,同時當(dāng)內(nèi)存短缺面臨Java VM崩潰拋出OOM前時,軟引用將會強制回收內(nèi)存,最后的虛引用一般沒有實際意義,僅僅觀察GC的活動狀態(tài),對于測試比較實用同時必須和ReferenceQueue一起使用。對于一組數(shù)據(jù),我們可以通過HashMap的方式來添加一組SoftReference對象來臨時保留一些數(shù)據(jù),同時對于需要反復(fù)通過網(wǎng)絡(luò)獲取的不經(jīng)常改變的內(nèi)容,可以通過本地的文件系統(tǒng)或數(shù)據(jù)庫來存儲緩存。
最后一句話說的很對,事實上大多數(shù)情況也是如此。
在說說它的用法吧,通常它作為一個adapter的一個變量如:
class BookAdapter extends ArrayAdapter
AsyncImageLoader asyncImageLoader;
Context mContext;
BookAdapter(Context context,List
super(context, 0, data);
asyncImageLoader = new AsyncImageLoader();
mContext = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewCache holder ;
if(convertView==null){
LayoutInflater inflate = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflate.inflate(com.slider.cn.R.layout.list_item , null);
holder = new ViewCache();
holder.icon = (ImageView)convertView.findViewById(com.slider.cn.R.id.note_icon);
holder.name = (TextView)convertView.findViewById(com.slider.cn.R.id.note_name);
holder.date = (TextView)convertView.findViewById(com.slider.cn.R.id.note_date);
convertView.setTag(holder);
}else{
holder = (ViewCache)convertView.getTag();
}
final BookInfo bookInfo = getItem(position);
holder.name.setText(bookInfo.getName().toString());
holder.date.setText(bookInfo.getInfo());
holder.icon.setTag(bookInfo.getUri());
//
Drawable drawable = asyncImageLoader.loadDrawable(bookInfo.getUri(), new ImageCallback() {
@Override
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag = (ImageView) BookListView.this.findViewWithTag(bookInfo.getUri());
if (imageViewByTag!=null) {
imageViewByTag.setImageDrawable(imageDrawable);
}else {
//load image failed from Internet
}
}
});
if(drawable==null){
holder.icon.setImageDrawable(drawable_waiting);
評論