使用 Volley

Volley 是一個 HTTP 庫,它能夠幫助 Android app 更方便地執行網絡操作,最重要的是,它更快速高效。我們可以通過開源的 AOSP 倉庫獲取到 Volley
Volley 不適合用來下載大的數據文件。因爲 Volley 會保持在解析的過程中所有的響應。對於下載大量的數據操作,請考慮使用 DownloadManager。

發送簡單的網絡請求

1)Add the INTERNET Permission

爲了使用Volley,你必須添加android.permission.INTERNET權限到你的manifest文件中。沒有這個權限,你的app將無法訪問網絡。

2)Use newRequestQueue

Volley提供了一個簡便的方法:Volley.newRequestQueue用來爲你建立一個RequestQueue,使用默認值,並啓動這個隊列。

public void sendSimpleRequest(){

        RequestQueue rQuene = Volley.newRequestQueue(this);
        String url = "https://www.baidu.com";

        Log.i("info", "send start");
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener(){
            @Override
            public void onResponse(Object response) {
                Log.i("info", response.toString());
                Toast.makeText(getApplicationContext(), response.toString().substring(0,500),
                        Toast.LENGTH_SHORT).show();

                Log.i("info", "send complete");
            }
        },new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("info", "error");
                Toast.makeText(getApplicationContext(), "error",
                        Toast.LENGTH_SHORT).show();
            }
        });

        //添加到請求隊列,發送請求
        rQuene.add(stringRequest);
        Log.i("info", "send end");
    }

建立請求隊列方式

建立網絡和緩存

一個 RequestQueue 需要兩部分來支持它的工作:一部分是網絡操作,用來傳輸請求,另外一個是用來處理緩存操作的 Cache。在 Volley 的工具箱中包含了標準的實現方式:DiskBasedCache 提供了每個文件與對應響應數據一一映射的緩存實現。 BasicNetwork 提供了一個基於 AndroidHttpClient 或者 HttpURLConnection 的網絡傳輸。

BasicNetwork 是 Volley 默認的網絡操作實現方式。一個 BasicNetwork 必須使用我們的 app 用於連接網絡的 HTTP Client 進行初始化。這個 Client 通常是AndroidHttpClient 或者 HttpURLConnection:

對於 app target API level 低於 API 9(Gingerbread)的使用 AndroidHttpClient。在 Gingerbread 之前,HttpURLConnection 是不可靠的。對於這個的細節,請參考 Android’s HTTP Clients。
對於 API Level 9 以及以上的,使用 HttpURLConnection。
具體代碼如下:

    private void sendRequestQueue() {
        //建立緩存
        Cache cache = new DiskBasedCache(getCacheDir(), 1024*1024);

        //
        Network network = new BasicNetwork(new HurlStack());

        RequestQueue rQueue = new RequestQueue(cache, network);

        rQueue.start();

        String url = "https://www.baidu.com";

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>(){
            @Override
            public void onResponse(String response) {
                Log.i("info", response);
                Toast.makeText(getApplicationContext(), response.substring(0, 500), Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener(){
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("info", error.toString());
            }
        });

        //把請求添加到隊列
        rQueue.add(stringRequest);
    }

使用單例模式下載圖片並顯示

如果我們的應用需要持續地使用網絡,更加高效的方式應該是建立一個 RequestQueue 的單例,這樣它能夠持續保持在整個 app 的生命週期中。我們可以通過多種方式來實現這個單例。推薦的方式是實現一個單例類,裏面封裝了 RequestQueue 對象與其它的 Volley 功能。另外一個方法是繼承 Application 類,並在 Application.OnCreate() 方法裏面建立 RequestQueue。但是我們並不推薦這個方法,因爲一個 static 的單例能夠以一種更加模塊化的方式提供同樣的功能。

一個關鍵的概念是 RequestQueue 必須使用 Application context 來實例化,而不是 Activity context。這確保了 RequestQueue 在我們 app 的生命週期中一直存活,而不會因爲 activity 的重新創建而被重新創建(例如,當用戶旋轉設備時)。

下面是一個單例類,提供了 RequestQueue 與 ImageLoader 功能:

public class MySingleton {
    private static MySingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;

    private MySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();

        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
            private final LruCache<String, Bitmap>
                    cache = new LruCache<String, Bitmap>(20);

            @Override
            public Bitmap getBitmap(String url) {
                return cache.get(url);
            }

            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                cache.put(url, bitmap);
            }
        });
    }

    public static synchronized MySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new MySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }
}

調用代碼

    private void getImageByUrl() {
        Toast.makeText(getApplicationContext(), "開始加載圖片", Toast.LENGTH_SHORT).show();
        String url = "http://i.imgur.com/7spzG.png";
        ImageRequest imageRequest = new ImageRequest(url, new Response.Listener(){
                @Override
                public void onResponse(Object response) {
                    imageView.setImageBitmap((Bitmap)response);
                    Toast.makeText(getApplicationContext(), "加載成功", Toast.LENGTH_SHORT).show();
                }
            },0,0,null, new Response.ErrorListener(){
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getApplicationContext(), "加載失敗", Toast.LENGTH_SHORT).show();
                }
            }
        );
        MySingleton.getInstance(this).addToRequestQueue(imageRequest);
    }

最後結果

請求網頁
這裏寫圖片描述

加載網絡圖片
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章