diff options
author | Anonymous <no-reply@google.com> | 2018-06-18 16:19:27 -0700 |
---|---|---|
committer | Jeff Davidson <jpd@google.com> | 2018-06-20 23:31:35 +0000 |
commit | 65d9fb8addc5e338cf485811379484b8fd5e3ccc (patch) | |
tree | c81fa90a1e8f5bca7c7faf978e7e3a6d4402f3ae /src/main | |
parent | 9a128540048414c78a2be9524f93b6234c640b3a (diff) | |
download | volley-65d9fb8addc5e338cf485811379484b8fd5e3ccc.tar.gz |
Import of Volley from GitHub to AOSP.android-p-preview-5android-p-preview-4android-o-mr1-iot-release-1.0.2
- b080a3488b0f82e0ef70191e8848c631376e80e0 Improve error message for null keys/values in getParams(... by Jeff Davidson <jpd236@cornell.edu>
- 2695d3cee7965418c01294a3c8b1ac191216ec6a Fix crash when using HurlStack with POST requests. (#202) by Jeff Davidson <jpd236@cornell.edu>
- 0c32d6a8865ebe0daf320d2bd7e32368e0cc31ba Re-raise swallowed interrupts and log warnings for spurio... by Jeff Davidson <jpd236@cornell.edu>
- 608f9827eadc869b4876f666f4d1a8bfafbeab2b Flesh out RetryPolicy's Javadoc. (#194) by Jeff Davidson <jpd236@cornell.edu>
- 0819be69fb7919db46778e970c169b5c0c3b9f71 Prevent duplicated/conflicting HTTP headers for HurlStack... by Jeff Davidson <jpd236@cornell.edu>
- cb1df92f5f18fc125441950a2fd53f3daa73e809 Use different cache keys for different methods. (#191) by Jeff Davidson <jpd236@cornell.edu>
- a0f4d39af7fce1649c45fa4eeaffa4d173c05f95 Add @Nullable annotations where necessary. (#185) by hackbar <7153163+hackbar@users.noreply.github.com>
GitOrigin-RevId: b080a3488b0f82e0ef70191e8848c631376e80e0
Change-Id: I0767443663d2118958f850dcf87b7ba89d9860b4
Diffstat (limited to 'src/main')
11 files changed, 101 insertions, 29 deletions
diff --git a/src/main/java/com/android/volley/CacheDispatcher.java b/src/main/java/com/android/volley/CacheDispatcher.java index 4ea8a0b..f616285 100644 --- a/src/main/java/com/android/volley/CacheDispatcher.java +++ b/src/main/java/com/android/volley/CacheDispatcher.java @@ -98,8 +98,12 @@ public class CacheDispatcher extends Thread { } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { + Thread.currentThread().interrupt(); return; } + VolleyLog.e( + "Ignoring spurious interrupt of CacheDispatcher thread; " + + "use quit() to terminate it"); } } } diff --git a/src/main/java/com/android/volley/NetworkDispatcher.java b/src/main/java/com/android/volley/NetworkDispatcher.java index 6e47465..327afed 100644 --- a/src/main/java/com/android/volley/NetworkDispatcher.java +++ b/src/main/java/com/android/volley/NetworkDispatcher.java @@ -91,8 +91,12 @@ public class NetworkDispatcher extends Thread { } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { + Thread.currentThread().interrupt(); return; } + VolleyLog.e( + "Ignoring spurious interrupt of NetworkDispatcher thread; " + + "use quit() to terminate it"); } } } diff --git a/src/main/java/com/android/volley/Request.java b/src/main/java/com/android/volley/Request.java index c958088..cd7290a 100644 --- a/src/main/java/com/android/volley/Request.java +++ b/src/main/java/com/android/volley/Request.java @@ -22,6 +22,7 @@ import android.os.Handler; import android.os.Looper; import android.support.annotation.CallSuper; import android.support.annotation.GuardedBy; +import android.support.annotation.Nullable; import android.text.TextUtils; import com.android.volley.VolleyLog.MarkerLog; import java.io.UnsupportedEncodingException; @@ -81,6 +82,7 @@ public abstract class Request<T> implements Comparable<Request<T>> { private final Object mLock = new Object(); /** Listener interface for errors. */ + @Nullable @GuardedBy("mLock") private Response.ErrorListener mErrorListener; @@ -91,6 +93,7 @@ public abstract class Request<T> implements Comparable<Request<T>> { private RequestQueue mRequestQueue; /** Whether or not responses to this request should be cached. */ + // TODO(#190): Turn this off by default for anything other than GET requests. private boolean mShouldCache = true; /** Whether or not this request has been canceled. */ @@ -139,7 +142,7 @@ public abstract class Request<T> implements Comparable<Request<T>> { * responses is provided by subclasses, who have a better idea of how to deliver an * already-parsed response. */ - public Request(int method, String url, Response.ErrorListener listener) { + public Request(int method, String url, @Nullable Response.ErrorListener listener) { mMethod = method; mUrl = url; mErrorListener = listener; @@ -174,6 +177,7 @@ public abstract class Request<T> implements Comparable<Request<T>> { } /** @return this request's {@link com.android.volley.Response.ErrorListener}. */ + @Nullable public Response.ErrorListener getErrorListener() { synchronized (mLock) { return mErrorListener; @@ -283,7 +287,18 @@ public abstract class Request<T> implements Comparable<Request<T>> { /** Returns the cache key for this request. By default, this is the URL. */ public String getCacheKey() { - return getUrl(); + String url = getUrl(); + // If this is a GET request, just use the URL as the key. + // For callers using DEPRECATED_GET_OR_POST, we assume the method is GET, which matches + // legacy behavior where all methods had the same cache key. We can't determine which method + // will be used because doing so requires calling getPostBody() which is expensive and may + // throw AuthFailureError. + // TODO(#190): Remove support for non-GET methods. + int method = getMethod(); + if (method == Method.GET || method == Method.DEPRECATED_GET_OR_POST) { + return url; + } + return Integer.toString(method) + '-' + url; } /** @@ -458,6 +473,14 @@ public abstract class Request<T> implements Comparable<Request<T>> { StringBuilder encodedParams = new StringBuilder(); try { for (Map.Entry<String, String> entry : params.entrySet()) { + if (entry.getKey() == null || entry.getValue() == null) { + throw new IllegalArgumentException( + String.format( + "Request#getParams() or Request#getPostParams() returned a map " + + "containing a null key or value: (%s, %s). All keys " + + "and values must be non-null.", + entry.getKey(), entry.getValue())); + } encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding)); encodedParams.append('='); encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding)); @@ -523,7 +546,7 @@ public abstract class Request<T> implements Comparable<Request<T>> { * remaining, this will cause delivery of a {@link TimeoutError} error. */ public final int getTimeoutMs() { - return mRetryPolicy.getCurrentTimeout(); + return getRetryPolicy().getCurrentTimeout(); } /** Returns the retry policy that should be used for this request. */ diff --git a/src/main/java/com/android/volley/RetryPolicy.java b/src/main/java/com/android/volley/RetryPolicy.java index aa6af43..3ef26de 100644 --- a/src/main/java/com/android/volley/RetryPolicy.java +++ b/src/main/java/com/android/volley/RetryPolicy.java @@ -16,7 +16,27 @@ package com.android.volley; -/** Retry policy for a request. */ +/** + * Retry policy for a request. + * + * <p>A retry policy can control two parameters: + * + * <ul> + * <li>The number of tries. This can be a simple counter or more complex logic based on the type + * of error passed to {@link #retry(VolleyError)}, although {@link #getCurrentRetryCount()} + * should always return the current retry count for logging purposes. + * <li>The request timeout for each try, via {@link #getCurrentTimeout()}. In the common case that + * a request times out before the response has been received from the server, retrying again + * with a longer timeout can increase the likelihood of success (at the expense of causing the + * user to wait longer, especially if the request still fails). + * </ul> + * + * <p>Note that currently, retries triggered by a retry policy are attempted immediately in sequence + * with no delay between them (although the time between tries may increase if the requests are + * timing out and {@link #getCurrentTimeout()} is returning increasing values). + * + * <p>By default, Volley uses {@link DefaultRetryPolicy}. + */ public interface RetryPolicy { /** Returns the current timeout (used for logging). */ diff --git a/src/main/java/com/android/volley/toolbox/HttpClientStack.java b/src/main/java/com/android/volley/toolbox/HttpClientStack.java index be0918a..1e9e4b0 100644 --- a/src/main/java/com/android/volley/toolbox/HttpClientStack.java +++ b/src/main/java/com/android/volley/toolbox/HttpClientStack.java @@ -58,7 +58,7 @@ public class HttpClientStack implements HttpStack { mClient = client; } - private static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) { + private static void setHeaders(HttpUriRequest httpRequest, Map<String, String> headers) { for (String key : headers.keySet()) { httpRequest.setHeader(key, headers.get(key)); } @@ -77,8 +77,10 @@ public class HttpClientStack implements HttpStack { public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders); - addHeaders(httpRequest, additionalHeaders); - addHeaders(httpRequest, request.getHeaders()); + setHeaders(httpRequest, additionalHeaders); + // Request.getHeaders() takes precedence over the given additional (cache) headers) and any + // headers set by createHttpRequest (like the Content-Type header). + setHeaders(httpRequest, request.getHeaders()); onPrepareRequest(httpRequest); HttpParams httpParams = httpRequest.getParams(); int timeoutMs = request.getTimeoutMs(); diff --git a/src/main/java/com/android/volley/toolbox/HurlStack.java b/src/main/java/com/android/volley/toolbox/HurlStack.java index dd73759..5af18ef 100644 --- a/src/main/java/com/android/volley/toolbox/HurlStack.java +++ b/src/main/java/com/android/volley/toolbox/HurlStack.java @@ -74,8 +74,9 @@ public class HurlStack extends BaseHttpStack { throws IOException, AuthFailureError { String url = request.getUrl(); HashMap<String, String> map = new HashMap<>(); - map.putAll(request.getHeaders()); map.putAll(additionalHeaders); + // Request.getHeaders() takes precedence over the given additional (cache) headers). + map.putAll(request.getHeaders()); if (mUrlRewriter != null) { String rewritten = mUrlRewriter.rewriteUrl(url); if (rewritten == null) { @@ -88,7 +89,7 @@ public class HurlStack extends BaseHttpStack { boolean keepConnectionOpen = false; try { for (String headerName : map.keySet()) { - connection.addRequestProperty(headerName, map.get(headerName)); + connection.setRequestProperty(headerName, map.get(headerName)); } setConnectionParametersForRequest(connection, request); // Initialize HttpResponse with data from the HttpURLConnection. @@ -219,6 +220,8 @@ public class HurlStack extends BaseHttpStack { return connection; } + // NOTE: Any request headers added here (via setRequestProperty or addRequestProperty) should be + // checked against the existing properties in the connection and not overridden if already set. @SuppressWarnings("deprecation") /* package */ static void setConnectionParametersForRequest( HttpURLConnection connection, Request<?> request) throws IOException, AuthFailureError { @@ -276,13 +279,16 @@ public class HurlStack extends BaseHttpStack { } private static void addBody(HttpURLConnection connection, Request<?> request, byte[] body) - throws IOException, AuthFailureError { + throws IOException { // Prepare output. There is no need to set Content-Length explicitly, // since this is handled by HttpURLConnection using the size of the prepared // output stream. connection.setDoOutput(true); - connection.addRequestProperty( - HttpHeaderParser.HEADER_CONTENT_TYPE, request.getBodyContentType()); + // Set the content-type unless it was already set (by Request#getHeaders). + if (!connection.getRequestProperties().containsKey(HttpHeaderParser.HEADER_CONTENT_TYPE)) { + connection.setRequestProperty( + HttpHeaderParser.HEADER_CONTENT_TYPE, request.getBodyContentType()); + } DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.write(body); out.close(); diff --git a/src/main/java/com/android/volley/toolbox/ImageRequest.java b/src/main/java/com/android/volley/toolbox/ImageRequest.java index c804267..59e468f 100644 --- a/src/main/java/com/android/volley/toolbox/ImageRequest.java +++ b/src/main/java/com/android/volley/toolbox/ImageRequest.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.support.annotation.GuardedBy; +import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.widget.ImageView.ScaleType; import com.android.volley.DefaultRetryPolicy; @@ -44,6 +45,7 @@ public class ImageRequest extends Request<Bitmap> { private final Object mLock = new Object(); @GuardedBy("mLock") + @Nullable private Response.Listener<Bitmap> mListener; private final Config mDecodeConfig; @@ -76,7 +78,7 @@ public class ImageRequest extends Request<Bitmap> { int maxHeight, ScaleType scaleType, Config decodeConfig, - Response.ErrorListener errorListener) { + @Nullable Response.ErrorListener errorListener) { super(Method.GET, url, errorListener); setRetryPolicy( new DefaultRetryPolicy( diff --git a/src/main/java/com/android/volley/toolbox/JsonArrayRequest.java b/src/main/java/com/android/volley/toolbox/JsonArrayRequest.java index 757c7f9..1abaec7 100644 --- a/src/main/java/com/android/volley/toolbox/JsonArrayRequest.java +++ b/src/main/java/com/android/volley/toolbox/JsonArrayRequest.java @@ -16,6 +16,7 @@ package com.android.volley.toolbox; +import android.support.annotation.Nullable; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Response; @@ -35,7 +36,8 @@ public class JsonArrayRequest extends JsonRequest<JSONArray> { * @param listener Listener to receive the JSON response * @param errorListener Error listener, or null to ignore errors. */ - public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) { + public JsonArrayRequest( + String url, Listener<JSONArray> listener, @Nullable ErrorListener errorListener) { super(Method.GET, url, null, listener, errorListener); } @@ -44,17 +46,17 @@ public class JsonArrayRequest extends JsonRequest<JSONArray> { * * @param method the HTTP method to use * @param url URL to fetch the JSON from - * @param jsonRequest A {@link JSONArray} to post with the request. Null is allowed and - * indicates no parameters will be posted along with request. + * @param jsonRequest A {@link JSONArray} to post with the request. Null indicates no parameters + * will be posted along with request. * @param listener Listener to receive the JSON response * @param errorListener Error listener, or null to ignore errors. */ public JsonArrayRequest( int method, String url, - JSONArray jsonRequest, + @Nullable JSONArray jsonRequest, Listener<JSONArray> listener, - ErrorListener errorListener) { + @Nullable ErrorListener errorListener) { super( method, url, diff --git a/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java b/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java index e9dc3d7..cee5efe 100644 --- a/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java +++ b/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java @@ -16,6 +16,7 @@ package com.android.volley.toolbox; +import android.support.annotation.Nullable; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Response; @@ -36,17 +37,17 @@ public class JsonObjectRequest extends JsonRequest<JSONObject> { * * @param method the HTTP method to use * @param url URL to fetch the JSON from - * @param jsonRequest A {@link JSONObject} to post with the request. Null is allowed and - * indicates no parameters will be posted along with request. + * @param jsonRequest A {@link JSONObject} to post with the request. Null indicates no + * parameters will be posted along with request. * @param listener Listener to receive the JSON response * @param errorListener Error listener, or null to ignore errors. */ public JsonObjectRequest( int method, String url, - JSONObject jsonRequest, + @Nullable JSONObject jsonRequest, Listener<JSONObject> listener, - ErrorListener errorListener) { + @Nullable ErrorListener errorListener) { super( method, url, @@ -63,9 +64,9 @@ public class JsonObjectRequest extends JsonRequest<JSONObject> { */ public JsonObjectRequest( String url, - JSONObject jsonRequest, + @Nullable JSONObject jsonRequest, Listener<JSONObject> listener, - ErrorListener errorListener) { + @Nullable ErrorListener errorListener) { this( jsonRequest == null ? Method.GET : Method.POST, url, diff --git a/src/main/java/com/android/volley/toolbox/JsonRequest.java b/src/main/java/com/android/volley/toolbox/JsonRequest.java index fd395dd..c00d3db 100644 --- a/src/main/java/com/android/volley/toolbox/JsonRequest.java +++ b/src/main/java/com/android/volley/toolbox/JsonRequest.java @@ -17,6 +17,7 @@ package com.android.volley.toolbox; import android.support.annotation.GuardedBy; +import android.support.annotation.Nullable; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; @@ -42,10 +43,11 @@ public abstract class JsonRequest<T> extends Request<T> { /** Lock to guard mListener as it is cleared on cancel() and read on delivery. */ private final Object mLock = new Object(); + @Nullable @GuardedBy("mLock") private Listener<T> mListener; - private final String mRequestBody; + @Nullable private final String mRequestBody; /** * Deprecated constructor for a JsonRequest which defaults to GET unless {@link #getPostBody()} @@ -62,9 +64,9 @@ public abstract class JsonRequest<T> extends Request<T> { public JsonRequest( int method, String url, - String requestBody, + @Nullable String requestBody, Listener<T> listener, - ErrorListener errorListener) { + @Nullable ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; mRequestBody = requestBody; diff --git a/src/main/java/com/android/volley/toolbox/StringRequest.java b/src/main/java/com/android/volley/toolbox/StringRequest.java index 0fbab14..c4c89b5 100644 --- a/src/main/java/com/android/volley/toolbox/StringRequest.java +++ b/src/main/java/com/android/volley/toolbox/StringRequest.java @@ -17,6 +17,7 @@ package com.android.volley.toolbox; import android.support.annotation.GuardedBy; +import android.support.annotation.Nullable; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; @@ -30,6 +31,7 @@ public class StringRequest extends Request<String> { /** Lock to guard mListener as it is cleared on cancel() and read on delivery. */ private final Object mLock = new Object(); + @Nullable @GuardedBy("mLock") private Listener<String> mListener; @@ -42,7 +44,10 @@ public class StringRequest extends Request<String> { * @param errorListener Error listener, or null to ignore errors */ public StringRequest( - int method, String url, Listener<String> listener, ErrorListener errorListener) { + int method, + String url, + Listener<String> listener, + @Nullable ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; } @@ -54,7 +59,8 @@ public class StringRequest extends Request<String> { * @param listener Listener to receive the String response * @param errorListener Error listener, or null to ignore errors */ - public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) { + public StringRequest( + String url, Listener<String> listener, @Nullable ErrorListener errorListener) { this(Method.GET, url, listener, errorListener); } |