1. 程式人生 > >Android異步載入全解析之開篇瞎扯淡

Android異步載入全解析之開篇瞎扯淡

com des turn pro 能夠 eat launch 卡頓 ring

Android異步載入

概述

Android異步載入在Android中使用的很廣泛,除了是由於避免在主線程中做網絡操作。更是為了避免在顯示時由於時間太長而造成ANR,添加顯示的流暢性,特別是像ListView、GridView這種控件。假設getView的時間太長,就會造成很嚴重的卡頓,很影響性能。
本系列將展示在Android中怎樣進行異步載入操作,並使用ListView來作為演示的對象。

怎樣下載圖像

下載自然是須要使用網絡,使用網絡就不能在主線程。在主線程就會爆炸。所以我們必須要在非主線程中去下載圖像。OK。那麽下載使用的方法呢。許多,這裏簡單的列舉幾種

HttpURLConnection

private static Bitmap getBitmapFromUrl(String urlString) {
    Bitmap bitmap;
    InputStream is = null;
    try {
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        is = new BufferedInputStream(conn.getInputStream());
        bitmap = BitmapFactory.decodeStream(is);
        conn.disconnect();
        return bitmap;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (is != null)
                is.close();
        } catch (IOException e) {
        }
    }
    return null;
}

很easy。甚至都沒做超時等處理。這裏偷個懶。

Drawable

Drawable d = Drawable.createFromStream(is, "url");

也很easy,僅僅是須要進行下轉換。

ListView

這一篇作為開篇。我們還是來扯下淡,這個ListView,大家都用過,最經常使用的優化也就是使用ViewHolder模式進行復用,避免反復的inflate和findViewById而影響效率,相信大部分的開發人員都已經熟知,這裏我們還是貼下Adapter的代碼:
package com.imooc.listviewacyncloader;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import java.util.List;

public class MyAdapterNotUseCaches extends BaseAdapter {

    private LayoutInflater mInflater;
    private List<String> mData;

    public MyAdapterNotUseCaches(Context context, List<String> data) {
        this.mData = data;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String url = mData.get(position);
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.listview_item, null);
            viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_lv_item);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.imageView.setTag(url);
        viewHolder.imageView.setImageResource(R.drawable.ic_launcher);
        return convertView;
    }

    public class ViewHolder{
        public ImageView imageView;
    }
}

確實很easy哈。最主要的ViewHolder模式使用ListView。只是,這裏有點須要註意的:
viewHolder.imageView.setTag(url);

這個事實上是很重要的,為什麽重要我們後面會繼續說。

除了這個地方,其他的部分,假設你能獨立寫出來。相信你已經擊敗了10%的開發人員了,後面我們再來講怎樣擊敗剩下90%的開發人員。


圖像

圖像我們能夠從網絡相冊裏面來獲取,這裏偶然找到郭神的一篇博客裏面的圖像地址,就無恥的拿來用了:
public class Images {

    public final static String[] IMAGE_URLS = new String[] {
            "http://img.my.csdn.net/uploads/201407/26/1406383299_1976.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383291_6518.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383291_8239.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383290_9329.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383290_1042.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383275_3977.jpg",
            "http://img.my.csdn.net/uploads/201407/26/1406383265_8550.jpg",
……
那麽我們在MainActivity中就能夠導入這些圖像了:
package com.imooc.listviewacyncloader;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

import java.util.Arrays;
import java.util.List;


public class MainActivity extends Activity {

    private ListView mListView;
    private List<String> mData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = (ListView) findViewById(R.id.lv);
        mData = Arrays.asList(Images.IMAGE_URLS);
        mListView.setAdapter(……);
    }
}

測試圖像搞定~我們後面繼續~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


我的Github
我的視頻 慕課網






Android異步載入全解析之開篇瞎扯淡