Menyiapkan RequestQueue

Tutorial sebelumnya menunjukkan kepada Anda cara menggunakan metode praktis Volley.newRequestQueue untuk menyiapkan RequestQueue dengan memanfaatkan perilaku default Volley. Tutorial ini memandu Anda dengan langkah-langkah eksplisit pembuatan RequestQueue untuk memungkinkan penyediaan perilaku kustom Anda sendiri.

Tutorial ini juga menjelaskan praktik yang disarankan untuk membuat RequestQueue sebagai singleton, yang membuat RequestQueue mampu bertahan seumur hidup aplikasi Anda.

Menyiapkan jaringan dan cache

RequestQueue membutuhkan dua hal untuk melakukan tugasnya: jaringan untuk melakukan transport permintaan, dan cache untuk menangani caching. Implementasi standar hal-hal tersebut tersedia di toolbox Volley: DiskBasedCache menyediakan cache satu-file-per-respons dengan indeks dalam memori, dan BasicNetwork menyediakan transportasi jaringan berdasarkan klien HTTP pilihan Anda.

BasicNetwork adalah implementasi jaringan standar Volley. BasicNetwork harus diinisialisasi dengan klien HTTP yang digunakan aplikasi Anda agar terhubung ke jaringan. Biasanya ini berupa HttpURLConnection.

Cuplikan ini menunjukkan kepada Anda langkah-langkah yang termasuk dalam menyiapkan RequestQueue:

Kotlin

    // Instantiate the cache
    val cache = DiskBasedCache(cacheDir, 1024 * 1024) // 1MB cap

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

    // Instantiate the RequestQueue with the cache and network. Start the queue.
    val requestQueue = RequestQueue(cache, network).apply {
        start()
    }

    val url = "http://www.example.com"

    // Formulate the request and handle the response.
    val stringRequest = StringRequest(Request.Method.GET, url,
             Response.Listener<String> { response ->
                // Do something with the response
            },
            Response.ErrorListener { error ->
                // Handle error
                textView.text = "ERROR: %s".format(error.toString())
            })

    // Add the request to the RequestQueue.
    requestQueue.add(stringRequest)

    // ...
    

Java

    RequestQueue requestQueue;

    // 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.
    requestQueue = new RequestQueue(cache, network);

    // Start the queue
    requestQueue.start();

    String url ="http://www.example.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.
    requestQueue.add(stringRequest);

    // ...
    

Jika Anda hanya perlu membuat permintaan satu kali dan tidak ingin meninggalkan kumpulan thread, Anda bisa membuat RequestQueue jika diperlukan dan memanggil stop() pada RequestQueue setelah respons atau error kembali, dengan menggunakan metode Volley.newRequestQueue() yang dijelaskan dalam Mengirim Permintaan Sederhana. Tetapi, kasus penggunaan yang lebih umum adalah membuat RequestQueue sebagai singleton agar tetap berjalan seumur hidup aplikasi Anda, seperti yang dijelaskan di bagian selanjutnya.

Menggunakan pola tunggal

Jika aplikasi Anda terus-menerus menggunakan jaringan, mungkin lebih efisien membuat satu instance RequestQueue yang akan bertahan seumur hidup aplikasi Anda. Anda bisa mencapainya dengan berbagai cara. Pendekatan yang disarankan adalah menerapkan class tunggal yang mencakup RequestQueue dan fungsionalitas Volley lainnya. Pendekatan yang lain adalah dengan membuat subclass Application dan menyiapkan RequestQueue di Application.onCreate(). Tetapi pendekatan ini tidak disarankan; suatu singleton statis dapat memberi fungsi yang sama dengan cara yang lebih modular.

Konsep utamanya adalah bahwa RequestQueue harus dipakai dengan konteks Application, bukan konteks Activity. Hal ini akan memastikan agar RequestQueue bertahan seumur hidup aplikasi Anda, dan bukan dibuat ulang setiap kali aktivitas diciptakan kembali (misalnya, saat pengguna memutar perangkat).

Berikut adalah contoh dari class singleton yang menyediakan fungsi RequestQueue dan ImageLoader:

Kotlin

    class MySingleton constructor(context: Context) {
        companion object {
            @Volatile
            private var INSTANCE: MySingleton? = null
            fun getInstance(context: Context) =
                INSTANCE ?: synchronized(this) {
                    INSTANCE ?: MySingleton(context).also {
                        INSTANCE = it
                    }
                }
        }
        val imageLoader: ImageLoader by lazy {
            ImageLoader(requestQueue,
                    object : ImageLoader.ImageCache {
                        private val cache = LruCache<String, Bitmap>(20)
                        override fun getBitmap(url: String): Bitmap {
                            return cache.get(url)
                        }
                        override fun putBitmap(url: String, bitmap: Bitmap) {
                            cache.put(url, bitmap)
                        }
                    })
        }
        val requestQueue: RequestQueue by lazy {
            // applicationContext is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            Volley.newRequestQueue(context.applicationContext)
        }
        fun <T> addToRequestQueue(req: Request<T>) {
            requestQueue.add(req)
        }
    }
    

Java

    public class MySingleton {
        private static MySingleton instance;
        private RequestQueue requestQueue;
        private ImageLoader imageLoader;
        private static Context ctx;

        private MySingleton(Context context) {
            ctx = context;
            requestQueue = getRequestQueue();

            imageLoader = new ImageLoader(requestQueue,
                    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 (instance == null) {
                instance = new MySingleton(context);
            }
            return instance;
        }

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

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

        public ImageLoader getImageLoader() {
            return imageLoader;
        }
    }
    

Berikut adalah beberapa contoh dalam melakukan operasi RequestQueue menggunakan class singleton:

Kotlin

    // Get a RequestQueue
    val queue = MySingleton.getInstance(this.applicationContext).requestQueue

    // ...

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

Java

    // 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);