맞춤 요청 구현

이 과정에서는 Volley 지원 기능이 기본 제공되지 않는 자체 맞춤 요청 유형을 구현하는 방법을 설명합니다.

맞춤 요청 작성

대부분의 요청은 도구상자에서 즉시 사용할 수 있습니다. 응답이 문자열, 이미지 또는 JSON인 경우 아마도 맞춤 Request를 구현할 필요가 없습니다.

맞춤 요청을 구현해야 하는 경우 다음과 같이 하면 됩니다.

  • Request<T> 클래스를 확장합니다. 여기서 <T>는 요청에서 예상하는 파싱된 응답의 유형을 나타냅니다. 따라서, 예를 들어 파싱된 응답이 문자열인 경우 Request<String>을 확장하여 맞춤 요청을 만드세요. Request<T>를 확장하는 예는 Volley 도구상자 클래스 StringRequestImageRequest를 참조하세요.
  • 아래에 자세히 설명된 추상 메서드 parseNetworkResponse()deliverResponse()를 구현합니다.

parseNetworkResponse

Response은 지정된 유형(예: 문자열, 이미지 또는 JSON)에 따라 전달할 파싱된 응답을 캡슐화합니다. 다음은 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
    // ...
    }
    

자바

    @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
    // ...
    }
    

다음 사항을 참고하세요.

  • parseNetworkResponse() 에서는 응답 페이로드가 byte[], HTTP 상태 코드 및 응답 헤더로 포함된 NetworkResponse를 매개변수로 사용합니다.
  • 구현에서는 입력한 응답 개체 및 캐시 메타데이터 또는 파싱 실패의 경우 오류가 포함된 Response<T>를 반환해야 합니다.

프로토콜에 표준이 아닌 캐시 의미 체계가 포함되어 있는 경우 Cache.Entry를 직접 빌드할 수 있지만 대부분 요청의 경우 다음과 같이 하면 됩니다.

Kotlin

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

자바

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

Volley는 작업자 스레드에서 parseNetworkResponse()를 호출합니다. 이에 따라 JPEG을 비트맵으로 디코딩하는 것과 같이 많은 비용이 드는 파싱 작업이 UI 스레드를 차단하지 않습니다.

deliverResponse

Volley는 기본 스레드에서 parseNetworkResponse()에서 반환한 개체를 사용하여 콜백합니다. 대부분의 요청은 여기에서 콜백 인터페이스를 호출합니다. 예:

Kotlin

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

자바

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

예: GsonRequest

Gson은 리플렉션을 사용하여 Java 개체와 JSON 간을 변환하는 라이브러리입니다. 해당하는 JSON 키와 이름이 동일한 자바 개체를 정의하고 Gson에 클래스 개체를 전달하면 Gson에서 필드를 채웁니다. 다음은 Gson을 파싱에 사용하는 Volley 요청의 전체 구현입니다.

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))
            }
        }
    }
    

자바

    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에서 즉시 사용 가능한 JsonArrayRequestJsonArrayObject 클래스를 제공합니다. 자세한 내용은 표준 요청 실행을 참조하세요.