Menerapkan permintaan kustom

Tutorial ini menjelaskan cara menggunakan jenis permintaan khusus Anda yang tidak mendapat dukungan unik Volley:

Menuliskan permintaan khusus

Sebagian besar permintaan memiliki implementasi siap pakai dalam toolbox; jika respons berupa string, gambar, atau JSON, Anda mungkin tidak perlu menerapkan Request khusus.

Apabila Anda perlu menerapkan permintaan khusus, berikut hal-hal yang perlu dilakukan:

  • Perpanjang class Request<T>, di mana <T> mewakili jenis respons terurai yang diminta oleh permintaan. Jika respons yang terurai adalah string, misalnya, buat permintaan khusus dengan memperpanjang Request<String>. Lihat class toolbox Volley StringRequest dan ImageRequest untuk contoh Request<T> yang diperpanjang.
  • Terapkan metode abstrak parseNetworkResponse() dan deliverResponse() yang dijelaskan secara lebih detail di bawah ini.

parseNetworkResponse

Suatu Response merangkum respons yang diurai untuk pengiriman jenis yang ditentukan (seperti string, gambar, atau JSON). Berikut adalah ini sampel implementasi parseNetworkResponse():

Kotlin

    override fun parseNetworkResponse(response: NetworkResponse?): Response<T> {
        return try {
            val json = String(
                    response?.data ?: ByteArray(0),
                    Charset.forName(HttpHeaderParser.parseCharset(response?.headers)))
            Response.success(
                    gson.fromJson(json, clazz),
                    HttpHeaderParser.parseCacheHeaders(response))
        }
        // handle errors
    // ...
    }
    

Java

    @Override
    protected Response<T> parseNetworkResponse(
            NetworkResponse response) {
        try {
            String json = new String(response.data,
            HttpHeaderParser.parseCharset(response.headers));
        return Response.success(gson.fromJson(json, clazz),
        HttpHeaderParser.parseCacheHeaders(response));
        }
        // handle errors
    // ...
    }
    

Perhatikan berikut ini:

  • parseNetworkResponse() mengambil NetworkResponse sebagai parameternya yang berisi payload respons sebagai byte[], kode status HTTP, dan header respons.
  • Implementasi Anda harus mengembalikan Response<T> yang berisi objek respons yang diketik dan metadata cache atau suatu error, seperti dalam kasus kegagalan urai.

Jika protokol Anda memiliki semantik cache nonstandar, Anda bisa membuat Cache.Entry sendiri, tetapi sebagian besar permintaan akan tetap berfungsi dengan hal seperti ini:

Kotlin

    return Response.success(myDecodedObject,
            HttpHeaderParser.parseCacheHeaders(response))
    

Java

    return Response.success(myDecodedObject,
            HttpHeaderParser.parseCacheHeaders(response));
    

Volley akan memanggil parseNetworkResponse() dari thread pekerja. Ini memastikan bahwa operasi parsing yang mahal, seperti dekode JPEG ke dalam Bitmap, tidak memblokir UI thread.

deliverResponse

Volley memanggil Anda kembali ke thread utama dengan objek yang Anda kembalikan di parseNetworkResponse(). Sebagian besar permintaan akan memanggil antarmuka callback di sini, misalnya:

Kotlin

    override fun deliverResponse(response: T) = listener.onResponse(response)
    

Java

    protected void deliverResponse(T response) {
            listener.onResponse(response);
    

Contoh: GsonRequest

Gson adalah library untuk mengonversi objek Java ke dan dari JSON menggunakan refleksi. Anda bisa menentukan objek Java yang memiliki nama yang sama dengan kunci JSON yang sesuai, meneruskan objek kelas pada GSON, dan Gson akan mengisi kolomnya untuk Anda. Berikut ini adalah implementasi lengkap permintaan Volley yang menggunakan Gson untuk penguraian:

Kotlin

    /**
     * Make a GET request and return a parsed object from JSON.
     *
     * @param url URL of the request to make
     * @param clazz Relevant class object, for Gson's reflection
     * @param headers Map of request headers
     */
    class GsonRequest<T>(
            url: String,
            private val clazz: Class<T>,
            private val headers: MutableMap<String, String>?,
            private val listener: Response.Listener<T>,
            errorListener: Response.ErrorListener
    ) : Request<T>(Method.GET, url, errorListener) {
        private val gson = Gson()

        override fun getHeaders(): MutableMap<String, String> = headers ?: super.getHeaders()

        override fun deliverResponse(response: T) = listener.onResponse(response)

        override fun parseNetworkResponse(response: NetworkResponse?): Response<T> {
            return try {
                val json = String(
                        response?.data ?: ByteArray(0),
                        Charset.forName(HttpHeaderParser.parseCharset(response?.headers)))
                Response.success(
                        gson.fromJson(json, clazz),
                        HttpHeaderParser.parseCacheHeaders(response))
            } catch (e: UnsupportedEncodingException) {
                Response.error(ParseError(e))
            } catch (e: JsonSyntaxException) {
                Response.error(ParseError(e))
            }
        }
    }
    

Java

    public class GsonRequest<T> extends Request<T> {
        private final Gson gson = new Gson();
        private final Class<T> clazz;
        private final Map<String, String> headers;
        private final Listener<T> listener;

        /**
         * Make a GET request and return a parsed object from JSON.
         *
         * @param url URL of the request to make
         * @param clazz Relevant class object, for Gson's reflection
         * @param headers Map of request headers
         */
        public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
                Listener<T> listener, ErrorListener errorListener) {
            super(Method.GET, url, errorListener);
            this.clazz = clazz;
            this.headers = headers;
            this.listener = listener;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            return headers != null ? headers : super.getHeaders();
        }

        @Override
        protected void deliverResponse(T response) {
            listener.onResponse(response);
        }

        @Override
        protected Response<T> parseNetworkResponse(NetworkResponse response) {
            try {
                String json = new String(
                        response.data,
                        HttpHeaderParser.parseCharset(response.headers));
                return Response.success(
                        gson.fromJson(json, clazz),
                        HttpHeaderParser.parseCacheHeaders(response));
            } catch (UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            } catch (JsonSyntaxException e) {
                return Response.error(new ParseError(e));
            }
        }
    }
    

Volley menyediakan class JsonArrayRequest dan JsonArrayObject siap pakai jika Anda lebih memilih untuk mengambil pendekatan tersebut. Lihat Membuat permintaan standar untuk informasi selengkapnya.