Android 建立請求隊列(RequestQueue)

2018-08-02 17:45 更新

編寫:kesenhoo - 原文:http://developer.android.com/training/volley/requestqueue.html

前一節(jié)課演示了如何使用 Volley.newRequestQueue 這一簡便的方法來建立一個RequestQueue,這是利用了 Volley 默認(rèn)行為的優(yōu)勢。這節(jié)課會介紹如何顯式地建立一個 RequestQueue,以便滿足我們自定義的需求。

這節(jié)課同樣會介紹一種推薦的實現(xiàn)方式:創(chuàng)建一個單例的 RequestQueue,這使得 RequestQueue 能夠持續(xù)保持在我們 app 的生命周期中。

建立網(wǎng)絡(luò)和緩存

一個 RequestQueue 需要兩部分來支持它的工作:一部分是網(wǎng)絡(luò)操作,用來傳輸請求,另外一個是用來處理緩存操作的 Cache。在 Volley 的工具箱中包含了標(biāo)準(zhǔn)的實現(xiàn)方式:DiskBasedCache 提供了每個文件與對應(yīng)響應(yīng)數(shù)據(jù)一一映射的緩存實現(xiàn)。 BasicNetwork 提供了一個基于 AndroidHttpClient 或者 HttpURLConnection 的網(wǎng)絡(luò)傳輸。

BasicNetwork 是 Volley 默認(rèn)的網(wǎng)絡(luò)操作實現(xiàn)方式。一個 BasicNetwork 必須使用我們的 app 用于連接網(wǎng)絡(luò)的 HTTP Client 進(jìn)行初始化。這個 Client 通常是AndroidHttpClient 或者 HttpURLConnection

  • 對于 app target API level 低于 API 9(Gingerbread)的使用 AndroidHttpClient。在 Gingerbread 之前,HttpURLConnection 是不可靠的。對于這個的細(xì)節(jié),請參考 Android's HTTP Clients。
  • 對于 API Level 9 以及以上的,使用 HttpURLConnection。

我們可以通過檢查系統(tǒng)版本選擇合適的 HTTP Client,從而創(chuàng)建一個能夠運(yùn)行在所有 Android 版本上的應(yīng)用。例如:

HttpStack stack;
...
// If the device is running a version >= Gingerbread...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
    // ...use HttpURLConnection for stack.
} else {
    // ...use AndroidHttpClient for stack.
}
Network network = new BasicNetwork(stack);

下面的代碼片段演示了如何一步步建立一個 RequestQueue:

RequestQueue mRequestQueue;

// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap

// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());

// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);

// Start the queue
mRequestQueue.start();

String url ="http://www.myurl.com";

// Formulate the request and handle the response.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Do something with the response
    }
},
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // Handle error
    }
});

// Add the request to the RequestQueue.
mRequestQueue.add(stringRequest);
...

如果我們僅僅是想做一個單次的請求并且不想要線程池一直保留,我們可以通過使用在前面一課:發(fā)送一個簡單的請求(Sending a Simple Request)文章中提到的 Volley.newRequestQueue() 方法,在任何需要的時刻創(chuàng)建 RequestQueue,然后在我們的響應(yīng)回調(diào)里面執(zhí)行 stop() 方法來停止操作。但是更通常的做法是創(chuàng)建一個 RequestQueue 并設(shè)置為一個單例。下面部分將演示這種做法。

使用單例模式

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

一個關(guān)鍵的概念是 RequestQueue 必須使用 Application context 來實例化,而不是 Activity context。這確保了 RequestQueue 在我們 app 的生命周期中一直存活,而不會因為 activity 的重新創(chuàng)建而被重新創(chuàng)建(例如,當(dāng)用戶旋轉(zhuǎn)設(shè)備時)。

下面是一個單例類,提供了 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;
    }
}

下面演示了利用單例類來執(zhí)行 RequestQueue 的操作:

// Get a RequestQueue
RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
    getRequestQueue();
...

// Add a request (in this example, called stringRequest) to your RequestQueue.
MySingleton.getInstance(this).addToRequestQueue(stringRequest);


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號