Android非同步載入學習筆記之四:利用緩衝最佳化網路載入圖片及ListView載入最佳化

來源:互聯網
上載者:User

標籤:android開發   asynctask   listview最佳化   

       如果不做任何處理,直接用網路載入圖片在網速快的情況下可能沒什麼不好的感覺,但是如果使用移動流量或是網路不好的時候,問題就來了,要麼使用者會抱怨流量使用太多,要麼抱怨圖片載入太慢,如論從哪個角度出發,都不是好的體驗!要提高使用者體驗,我們就要使用緩衝。Android中資料緩衝的方式有很多,相關介紹的文章也比較多,比如http://blog.csdn.net/dahuaishu2010_/article/details/17093139和http://www.jb51.net/article/38162.htm等。今天學習是是Lru緩衝。

 Lru(Least Recently Used)近期最少使用演算法,即是在一定條件下LRU緩衝是把最近最少使用的資料移除,讓給最新讀取的資料。而往往最常讀取的,也是讀取次數最多的,所以,利用LRU緩衝,我們能夠提高應用的效率及使用者體驗度。Andorid本身提供了LruCache類來實現這個緩衝演算法 。

在ImageLoader中利用LruCache緩衝:

public class ImageLoader {
private LruCache<String, Bitmap> mCaches;// 建立LruCache對象
private ImageView mImageView;
private ListView listView;
private Set<ImageAsyncTask> mTask;


@SuppressLint("NewApi")
public ImageLoader(ListView listView) {
this.listView = listView;
mTask = new HashSet<ImageAsyncTask>();
int maxMemory = (int) Runtime.getRuntime().maxMemory();// 擷取最大可用記憶體
int cacheSize = maxMemory / 8;// 設定快取資料的最大佔用記憶體量為最大值1/8
mCaches = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();// 每次存入緩衝的時候調用,返回bitmap的大小
}
};
}


@SuppressLint("NewApi")
/**
* 增加快取資料,增加前判斷資料是否存在
* @description:
* @author ldm
* @date 2015-8-11 下午7:51:04
*/
public void setLruCaches(String url, Bitmap bitmap) {
if (getLruCaches(url) == null) {// 如果緩衝中不存在url對應的Bitmap,則把bitmap加入mCaches
mCaches.put(url, bitmap);
}
}


/**
* 從緩衝中擷取資料
* @description:
* @author ldm
* @date 2015-8-11 下午7:51:22
*/
@SuppressLint("NewApi")
public Bitmap getLruCaches(String url) {
return mCaches.get(url);// 通過url擷取緩衝中對應的bitmap


}


/**
*從url中擷取到Bitmap
* @description:
* @author ldm
* @date 2015-8-11 下午1:55:12
*/
public Bitmap getBitmapByUrl(String urlStr) {
Bitmap bitmap = null;
InputStream is = null;
try {
URL url = new URL(urlStr);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(con.getInputStream());
bitmap = BitmapFactory.decodeStream(is);
con.disconnect();
return bitmap;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
return null;
}


public void loadImgByAsyncTask(ImageView img, String url) {
mImageView = img;
// 從緩衝中取出圖片
Bitmap bitmap = getLruCaches(url);
if (bitmap == null) {// 如果能在中無圖片,則就從網路下載
mImageView.setImageResource(R.drawable.ic_launcher);//設定預設圖片
new ImageAsyncTask(url).execute(url);
}
else {// 緩衝中有圖片,則直接顯示出來
mImageView.setImageBitmap(bitmap);
}
}


private class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
private ImageView imageView;
private String mUrl;


public ImageAsyncTask(String mUrl) {
this.mUrl = mUrl;
}


@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = getBitmapByUrl(params[0]);// 擷取圖片
if (bitmap != null) {
setLruCaches(params[0], bitmap);
}
return getBitmapByUrl(params[0]);
}


@Override
protected void onPostExecute(Bitmap result) {
ImageView img = (ImageView) listView.findViewWithTag(mUrl);
if (img != null && result != null) {
imageView.setImageBitmap(result);
}
mTask.remove(this);
}
}


public void setImageView(int start, int end) {
for (int i = start; i < end; i++) {
String url = DataAdapter.URLS[i];
Bitmap bitmap = getLruCaches(url);
if (bitmap == null) {// 如果能在中無圖片,則就從網路下載
ImageAsyncTask task = new ImageAsyncTask(url);
task.execute(url);
mTask.add(task);
}
else {// 緩衝中有圖片,則直接顯示出來
ImageView img = (ImageView) listView.findViewWithTag(url);
img.setImageBitmap(bitmap);
}
}
}
public void stopAllTask(){
if(mTask.size()>0){
for (ImageAsyncTask task : mTask) {
task.cancel(false);
}
}
}
}

   對應ListView的資料配接器DataAdapter:

public class DataAdapter extends BaseAdapter implements OnScrollListener {
private Context mContext;
private List<DataBean> list;
private ImageLoader mImageLoader;
private int mSart;
private int mEnd;
public static String[] URLS;
private ListView listView;
private boolean isFirst;//是否是第一次進入 
public DataAdapter(Context mContext, List<DataBean> list, ListView listView) {
this.listView = listView;
this.mContext = mContext;
this.list = list;
mImageLoader = new ImageLoader(listView);
URLS = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
URLS[i] = list.get(i).getImgUrl();
}
isFirst=true;
listView.setOnScrollListener(this);
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}

@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return list.get(arg0);
}

@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}

@Override
public View getView(int arg0, View view, ViewGroup arg2) {
ViewHolder holder = null;
if (view == null) {
holder = new ViewHolder();
view = LayoutInflater.from(mContext).inflate(R.layout.item_layout, null);
holder.iv = (ImageView) view.findViewById(R.id.item_iv);
holder.titleTv = (TextView) view.findViewById(R.id.item_title);
holder.contentTv = (TextView) view.findViewById(R.id.item_content);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
holder.titleTv.setText(list.get(arg0).getTitle());
holder.contentTv.setText(list.get(arg0).getContent());
holder.iv.setTag(list.get(arg0).getImgUrl());// 為ImageView設定tag
// new ImageLoader().loaderImageThread(holder.iv, list.get(arg0).getImgUrl());//用線程載入圖片
mImageLoader.loadImgByAsyncTask(holder.iv, list.get(arg0).getImgUrl());
return view;
}

/***
* ListView在流動過程中調用 
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
mSart = firstVisibleItem;// 可見第一個item
mEnd = firstVisibleItem + visibleItemCount;// 可見的最後一個item
if(isFirst&&visibleItemCount>0){//第一次載入資料時資料處理
mImageLoader.setImageView(mSart, mEnd);
isFirst=false;
}
}

/***
* ListView在流動狀態變化時調用 
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {// 流動停止,此時載入可見項資料
mImageLoader.setImageView(mSart, mEnd);
}
else {// 停止載入資料
mImageLoader.stopAllTask();
}
}
class ViewHolder {
TextView titleTv;
TextView contentTv;
ImageView iv;
}
}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Android非同步載入學習筆記之四:利用緩衝最佳化網路載入圖片及ListView載入最佳化

聯繫我們

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