1d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/* 2d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project 3d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 4d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License"); 5d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * you may not use this file except in compliance with the License. 6d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * You may obtain a copy of the License at 7d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 8d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * http://www.apache.org/licenses/LICENSE-2.0 9d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 10d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software 11d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS, 12d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * See the License for the specific language governing permissions and 14d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * limitations under the License. 15d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 16d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 17d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupackage com.android.volley; 18d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 19cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport android.net.TrafficStats; 20cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport android.net.Uri; 21d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.os.Handler; 22d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.os.Looper; 23d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.os.SystemClock; 24cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport android.text.TextUtils; 25cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 26cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport com.android.volley.VolleyLog.MarkerLog; 27d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 28d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.io.UnsupportedEncodingException; 29d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.net.URLEncoder; 30d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Collections; 31d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Map; 32d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 33d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/** 34d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Base class for all network requests. 35d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 36d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param <T> The type of parsed response this request expects. 37d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 38d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupublic abstract class Request<T> implements Comparable<Request<T>> { 39d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 40e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 41e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Default encoding for POST or PUT parameters. See {@link #getParamsEncoding()}. 42e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 43e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private static final String DEFAULT_PARAMS_ENCODING = "UTF-8"; 44e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 45e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 46e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Supported request methods. 47e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 48e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public interface Method { 49e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int DEPRECATED_GET_OR_POST = -1; 50e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int GET = 0; 51e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int POST = 1; 52e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int PUT = 2; 53e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int DELETE = 3; 54e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 55d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 56d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** An event log tracing the lifetime of this request; for debugging. */ 57d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final MarkerLog mEventLog = MarkerLog.ENABLED ? new MarkerLog() : null; 58d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 599e5c44f22b47fcb0d37c7b10de3b5db542424fa5Maurice Chu /** Request method of this request. Currently supports GET, POST, PUT, and DELETE. */ 60e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private final int mMethod; 61e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 62d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** URL of this request. */ 63d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final String mUrl; 64d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 65cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton /** Default tag for {@link TrafficStats}. */ 66cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton private final int mDefaultTrafficStatsTag; 67cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 68d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Listener interface for errors. */ 69d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final Response.ErrorListener mErrorListener; 70d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 71d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Sequence number of this request, used to enforce FIFO ordering. */ 72d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private Integer mSequence; 73d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 74d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** The request queue this request is associated with. */ 75d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private RequestQueue mRequestQueue; 76d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 77d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Whether or not responses to this request should be cached. */ 78d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private boolean mShouldCache = true; 79d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 80d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Whether or not this request has been canceled. */ 81d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private boolean mCanceled = false; 82d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 83d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Whether or not a response has been delivered for this request yet. */ 84d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private boolean mResponseDelivered = false; 85d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 86d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // A cheap variant of request tracing used to dump slow requests. 87d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private long mRequestBirthTime = 0; 88d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 89d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Threshold at which we should log the request (even when debug logging is not enabled). */ 90d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private static final long SLOW_REQUEST_THRESHOLD_MS = 3000; 91d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 92d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** The retry policy for this request. */ 93d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private RetryPolicy mRetryPolicy; 94d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 95d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 96d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * When a request can be retrieved from cache but must be refreshed from 97d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * the network, the cache entry will be stored here so that in the event of 98d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * a "Not Modified" response, we can be sure it hasn't been evicted from cache. 99d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 100d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private Cache.Entry mCacheEntry = null; 101d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 102d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** An opaque token tagging this request; used for bulk cancellation. */ 103d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private Object mTag; 104d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 105d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 106d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Creates a new request with the given URL and error listener. Note that 107d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * the normal response listener is not provided here as delivery of responses 108d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * is provided by subclasses, who have a better idea of how to deliver an 109d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * already-parsed response. 110e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 111e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #Request(int, String, com.android.volley.Response.ErrorListener)}. 112d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 113d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Request(String url, Response.ErrorListener listener) { 114e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru this(Method.DEPRECATED_GET_OR_POST, url, listener); 115e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 116e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 117e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 118e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Creates a new request with the given method (one of the values from {@link Method}), 119e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * URL, and error listener. Note that the normal response listener is not provided here as 120e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * delivery of responses is provided by subclasses, who have a better idea of how to deliver 121e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * an already-parsed response. 122e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 123e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public Request(int method, String url, Response.ErrorListener listener) { 124e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru mMethod = method; 125d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mUrl = url; 126d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mErrorListener = listener; 127d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru setRetryPolicy(new DefaultRetryPolicy()); 128cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 129cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode(); 130d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 131d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 132d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 133e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Return the method for this request. Can be one of the values in {@link Method}. 134e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 135e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public int getMethod() { 136e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return mMethod; 137e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 138e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 139e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 140d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Set a tag on this request. Can be used to cancel all requests with this 141d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * tag by {@link RequestQueue#cancelAll(Object)}. 142d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 143d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void setTag(Object tag) { 144d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mTag = tag; 145d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 146d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 147d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 148d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns this request's tag. 149d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @see Request#setTag(Object) 150d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 151d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Object getTag() { 152d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mTag; 153d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 154d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 155d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 156cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton * @return A tag for use with {@link TrafficStats#setThreadStatsTag(int)} 157cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton */ 158cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton public int getTrafficStatsTag() { 159cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton return mDefaultTrafficStatsTag; 160cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton } 161cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 162cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton /** 163d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Sets the retry policy for this request. 164d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 165d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void setRetryPolicy(RetryPolicy retryPolicy) { 166d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRetryPolicy = retryPolicy; 167d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 168d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 169d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 170d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Adds an event to this request's event log; for debugging. 171d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 172d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void addMarker(String tag) { 173d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (MarkerLog.ENABLED) { 174d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.add(tag, Thread.currentThread().getId()); 175d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } else if (mRequestBirthTime == 0) { 176d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRequestBirthTime = SystemClock.elapsedRealtime(); 177d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 178d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 179d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 180d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 181d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Notifies the request queue that this request has finished (successfully or with error). 182d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 183d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>Also dumps all events from this request's event log; for debugging.</p> 184d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 185d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru void finish(final String tag) { 186d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (mRequestQueue != null) { 187d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRequestQueue.finish(this); 188d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 189d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (MarkerLog.ENABLED) { 190d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru final long threadId = Thread.currentThread().getId(); 191d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (Looper.myLooper() != Looper.getMainLooper()) { 192d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // If we finish marking off of the main thread, we need to 193d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // actually do it on the main thread to ensure correct ordering. 194d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Handler mainThread = new Handler(Looper.getMainLooper()); 195d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mainThread.post(new Runnable() { 196d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 197d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void run() { 198d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.add(tag, threadId); 199d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.finish(this.toString()); 200d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 201d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru }); 202d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return; 203d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 204d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 205d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.add(tag, threadId); 206d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.finish(this.toString()); 207d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } else { 208d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime; 209d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) { 210d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru VolleyLog.d("%d ms: %s", requestTime, this.toString()); 211d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 212d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 213d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 214d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 215d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 216d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Associates this request with the given queue. The request queue will be notified when this 217d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * request has finished. 218d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 219d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void setRequestQueue(RequestQueue requestQueue) { 220d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRequestQueue = requestQueue; 221d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 222d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 223d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 224d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Sets the sequence number of this request. Used by {@link RequestQueue}. 225d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 226d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final void setSequence(int sequence) { 227d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mSequence = sequence; 228d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 229d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 230d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 231d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the sequence number of this request. 232d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 233d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final int getSequence() { 234d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (mSequence == null) { 235d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru throw new IllegalStateException("getSequence called before setSequence"); 236d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 237d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mSequence; 238d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 239d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 240d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 241d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the URL of this request. 242d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 243d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String getUrl() { 244d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mUrl; 245d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 246d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 247d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 248d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the cache key for this request. By default, this is the URL. 249d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 250d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String getCacheKey() { 251d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return getUrl(); 252d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 253d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 254d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 255d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Annotates this request with an entry retrieved for it from cache. 256d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Used for cache coherency support. 257d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 258d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void setCacheEntry(Cache.Entry entry) { 259d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mCacheEntry = entry; 260d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 261d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 262d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 263d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the annotated cache entry, or null if there isn't one. 264d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 265d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Cache.Entry getCacheEntry() { 266d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mCacheEntry; 267d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 268d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 269d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 270d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Mark this request as canceled. No callback will be delivered. 271d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 272d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void cancel() { 273d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mCanceled = true; 274d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 275d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 276d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 277d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns true if this request has been canceled. 278d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 279d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public boolean isCanceled() { 280d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mCanceled; 281d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 282d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 283d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 284d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns a list of extra HTTP headers to go along with this request. Can 285d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * throw {@link AuthFailureError} as authentication may be required to 286d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * provide these values. 287d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @throws AuthFailureError In the event of auth failure 288d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 289d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Map<String, String> getHeaders() throws AuthFailureError { 290d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return Collections.emptyMap(); 291d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 292d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 293d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 294d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns a Map of POST parameters to be used for this request, or null if 295d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * a simple GET should be used. Can throw {@link AuthFailureError} as 296d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * authentication may be required to provide these values. 297d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 298d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>Note that only one of getPostParams() and getPostBody() can return a non-null 299d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * value.</p> 300d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @throws AuthFailureError In the event of auth failure 301e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 302e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getParams()} instead. 303d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 304d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected Map<String, String> getPostParams() throws AuthFailureError { 305e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return getParams(); 306d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 307d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 308d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 309d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns which encoding should be used when converting POST parameters returned by 310d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * {@link #getPostParams()} into a raw POST body. 311d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 312d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>This controls both encodings: 313d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <ol> 314d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <li>The string encoding used when converting parameter names and values into bytes prior 315d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * to URL encoding them.</li> 316d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <li>The string encoding used when converting the URL encoded parameters into a raw 317d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * byte array.</li> 318d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * </ol> 319e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 320e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getParamsEncoding()} instead. 321d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 322d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected String getPostParamsEncoding() { 323e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return getParamsEncoding(); 324d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 325d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 326e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 327e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getBodyContentType()} instead. 328e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 329d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String getPostBodyContentType() { 330e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return getBodyContentType(); 331d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 332d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 333d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 334d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the raw POST body to be sent. 335d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 336d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @throws AuthFailureError In the event of auth failure 337e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 338e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getBody()} instead. 339d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 340d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public byte[] getPostBody() throws AuthFailureError { 341e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // Note: For compatibility with legacy clients of volley, this implementation must remain 342e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // here instead of simply calling the getBody() function because this function must 343e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // call getPostParams() and getPostParamsEncoding() since legacy clients would have 344e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // overridden these two member functions for POST requests. 345d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Map<String, String> postParams = getPostParams(); 346d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (postParams != null && postParams.size() > 0) { 347e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return encodeParameters(postParams, getPostParamsEncoding()); 348e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 349e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return null; 350e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 351e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 352e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 353e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Returns a Map of parameters to be used for a POST or PUT request. Can throw 354e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * {@link AuthFailureError} as authentication may be required to provide these values. 355e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 356e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <p>Note that you can directly override {@link #getBody()} for custom data.</p> 357e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 358e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @throws AuthFailureError in the event of auth failure 359e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 360e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru protected Map<String, String> getParams() throws AuthFailureError { 361e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return null; 362e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 363e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 364e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 365e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Returns which encoding should be used when converting POST or PUT parameters returned by 366e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * {@link #getParams()} into a raw POST or PUT body. 367e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 368e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <p>This controls both encodings: 369e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <ol> 370e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <li>The string encoding used when converting parameter names and values into bytes prior 371e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * to URL encoding them.</li> 372e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <li>The string encoding used when converting the URL encoded parameters into a raw 373e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * byte array.</li> 374e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * </ol> 375e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 376e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru protected String getParamsEncoding() { 377e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return DEFAULT_PARAMS_ENCODING; 378e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 379e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 380e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public String getBodyContentType() { 381e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return "application/x-www-form-urlencoded; charset=" + getParamsEncoding(); 382e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 383e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 384e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 385e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Returns the raw POST or PUT body to be sent. 386e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 387e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @throws AuthFailureError in the event of auth failure 388e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 389e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public byte[] getBody() throws AuthFailureError { 390e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru Map<String, String> params = getParams(); 391e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru if (params != null && params.size() > 0) { 392e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return encodeParameters(params, getParamsEncoding()); 393d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 394d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return null; 395d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 396d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 397d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 398e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Converts <code>params</code> into an application/x-www-form-urlencoded encoded string. 399d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 400e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) { 401d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru StringBuilder encodedParams = new StringBuilder(); 402d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru try { 403e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru for (Map.Entry<String, String> entry : params.entrySet()) { 404e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding)); 405d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru encodedParams.append('='); 406e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding)); 407d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru encodedParams.append('&'); 408d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 409e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return encodedParams.toString().getBytes(paramsEncoding); 410d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } catch (UnsupportedEncodingException uee) { 411e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee); 412d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 413d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 414d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 415d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 416d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Set whether or not responses to this request should be cached. 417d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 418d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final void setShouldCache(boolean shouldCache) { 419d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mShouldCache = shouldCache; 420d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 421d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 422d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 423d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns true if responses to this request should be cached. 424d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 425d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final boolean shouldCache() { 426d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mShouldCache; 427d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 428d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 429d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 430d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Priority values. Requests will be processed from higher priorities to 431d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * lower priorities, in FIFO order. 432d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 433d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public enum Priority { 434d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru LOW, 435d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru NORMAL, 436d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru HIGH, 437d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru IMMEDIATE 438d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 439d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 440d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 441d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default. 442d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 443d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Priority getPriority() { 444d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return Priority.NORMAL; 445d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 446d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 447d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 448d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the socket timeout in milliseconds per retry attempt. (This value can be changed 449d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * per retry attempt if a backoff is specified via backoffTimeout()). If there are no retry 450d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * attempts remaining, this will cause delivery of a {@link TimeoutError} error. 451d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 452d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final int getTimeoutMs() { 453d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mRetryPolicy.getCurrentTimeout(); 454d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 455d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 456d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 457d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the retry policy that should be used for this request. 458d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 459d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public RetryPolicy getRetryPolicy() { 460d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mRetryPolicy; 461d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 462d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 463d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 464d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Mark this request as having a response delivered on it. This can be used 465d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * later in the request's lifetime for suppressing identical responses. 466d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 467d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void markDelivered() { 468d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mResponseDelivered = true; 469d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 470d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 471d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 472d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns true if this request has had a response delivered for it. 473d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 474d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public boolean hasHadResponseDelivered() { 475d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mResponseDelivered; 476d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 477d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 478d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 479d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Subclasses must implement this to parse the raw network response 480d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * and return an appropriate response type. This method will be 481d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * called from a worker thread. The response will not be delivered 482d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * if you return null. 483d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param response Response from the network 484d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @return The parsed response, or null in the case of an error 485d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 486d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru abstract protected Response<T> parseNetworkResponse(NetworkResponse response); 487d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 488d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 489d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Subclasses can override this method to parse 'networkError' and return a more specific error. 490d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 491d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>The default implementation just returns the passed 'networkError'.</p> 492d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 493d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param volleyError the error retrieved from the network 494d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @return an NetworkError augmented with additional information 495d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 496d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected VolleyError parseNetworkError(VolleyError volleyError) { 497d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return volleyError; 498d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 499d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 500d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 501d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Subclasses must implement this to perform delivery of the parsed 502d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * response to their listeners. The given response is guaranteed to 503d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * be non-null; responses that fail to parse are not delivered. 504d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param response The parsed response returned by 505d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * {@link #parseNetworkResponse(NetworkResponse)} 506d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 507d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru abstract protected void deliverResponse(T response); 508d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 509d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 510d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Delivers error message to the ErrorListener that the Request was 511d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * initialized with. 512d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 513d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param error Error details 514d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 515d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void deliverError(VolleyError error) { 516d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (mErrorListener != null) { 517d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mErrorListener.onErrorResponse(error); 518d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 519d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 520d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 521d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 522d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Our comparator sorts from high to low priority, and secondarily by 523d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * sequence number to provide FIFO ordering. 524d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 525d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 526d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public int compareTo(Request<T> other) { 527d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Priority left = this.getPriority(); 528d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Priority right = other.getPriority(); 529d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 530d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // High-priority requests are "lesser" so they are sorted to the front. 531d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Equal priorities are sorted by sequence number to provide FIFO ordering. 532d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return left == right ? 533d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru this.mSequence - other.mSequence : 534d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru right.ordinal() - left.ordinal(); 535d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 536d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 537d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 538d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String toString() { 539cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton String trafficStatsTag = "0x" + Integer.toHexString(getTrafficStatsTag()); 540cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton return (mCanceled ? "[X] " : "[ ] ") + getUrl() + " " + trafficStatsTag + " " 541cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton + getPriority() + " " + mSequence; 542d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 543d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru} 544