Menyiapkan RequestQueue

Tutorial sebelumnya menunjukkan cara menggunakan metode praktis Volley.newRequestQueue untuk menyiapkan RequestQueue dengan memanfaatkan perilaku default Volley. Tutorial ini memberikan panduan dengan langkah-langkah yang jelas untuk membuat RequestQueue sehingga Anda dapat menyediakan perilaku kustom Anda sendiri.

Tutorial ini juga menjelaskan praktik yang direkomendasikan untuk membuat RequestQueue sebagai singleton sehingga RequestQueue dapat bertahan sepanjang waktu penggunaan aplikasi Anda.

Menyiapkan jaringan dan cache

RequestQueue memerlukan dua hal untuk melakukan tugasnya: jaringan untuk membawa permintaan, dan cache untuk menangani penyimpanan data ke dalam cache. Tersedia implementasi standar untuknya 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 penerapan jaringan default Volley. BasicNetwork harus diinisialisasi dengan klien HTTP yang digunakan aplikasi untuk terhubung ke jaringan. Biasanya, klien ini adalah HttpURLConnection.

Cuplikan berikut menunjukkan langkah-langkah yang diperlukan 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 hanya perlu membuat permintaan satu kali dan tidak ingin meninggalkan kumpulan thread, Anda dapat membuat RequestQueue di mana pun Anda membutuhkannya lalu memanggil stop() pada RequestQueue setelah respons atau error kembali, menggunakan metode Volley.newRequestQueue() yang dijelaskan dalam Mengirim Permintaan Sederhana. Namun, kasus penggunaan yang lebih umum adalah membuat RequestQueue sebagai singleton agar tetap berjalan sepanjang waktu penggunaan aplikasi Anda, seperti yang dijelaskan di bagian berikutnya.

Menggunakan pola singleton

Jika aplikasi Anda terus-menerus menggunakan jaringan, cara yang paling efisien mungkin adalah menyiapkan satu instance RequestQueue yang akan bertahan sepanjang waktu penggunaan aplikasi. Anda dapat melakukannya dengan berbagai cara. Pendekatan yang direkomendasikan adalah mengimplementasikan class singleton yang mengenkapsulasi RequestQueue dan fungsionalitas Volley lainnya. Pendekatan lainnya adalah membuat subclass Application dan menyiapkan RequestQueue di Application.onCreate(). Namun, pendekatan ini tidak disarankan; singleton statis dapat memberikan fungsi yang sama dengan cara yang lebih modular.

Konsep utamanya adalah, RequestQueue harus dibuat instance-nya dengan konteks Application, bukan konteks Activity. Hal ini memastikan RequestQueue akan bertahan sepanjang waktu penggunaan aplikasi Anda, bukan dibuat ulang setiap kali aktivitas dibuat ulang (misalnya, saat pengguna memutar perangkat).

Berikut adalah contoh class singleton yang menyediakan fungsionalitas 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 beberapa contoh tentang menjalankan 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);