PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/frameworks/support/volley/src/com/android/volley/Request.java

https://gitlab.com/brian0218/rk3066_r-box_android4.2.2_sdk
Java | 432 lines | 184 code | 56 blank | 192 comment | 20 complexity | 1c9e1017e7a27489c04bfd9296882ba8 MD5 | raw file
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.android.volley;
  17. import android.os.Handler;
  18. import android.os.Looper;
  19. import android.os.SystemClock;
  20. import com.android.volley.VolleyLog.MarkerLog;
  21. import java.io.UnsupportedEncodingException;
  22. import java.net.URLEncoder;
  23. import java.util.Collections;
  24. import java.util.Map;
  25. /**
  26. * Base class for all network requests.
  27. *
  28. * @param <T> The type of parsed response this request expects.
  29. */
  30. public abstract class Request<T> implements Comparable<Request<T>> {
  31. /** Default encoding for POST parameters. See {@link #getPostParamsEncoding()}. */
  32. private static final String DEFAULT_POST_PARAMS_ENCODING = "UTF-8";
  33. /** An event log tracing the lifetime of this request; for debugging. */
  34. private final MarkerLog mEventLog = MarkerLog.ENABLED ? new MarkerLog() : null;
  35. /** URL of this request. */
  36. private final String mUrl;
  37. /** Listener interface for errors. */
  38. private final Response.ErrorListener mErrorListener;
  39. /** Sequence number of this request, used to enforce FIFO ordering. */
  40. private Integer mSequence;
  41. /** The request queue this request is associated with. */
  42. private RequestQueue mRequestQueue;
  43. /** Whether or not responses to this request should be cached. */
  44. private boolean mShouldCache = true;
  45. /** Whether or not this request has been canceled. */
  46. private boolean mCanceled = false;
  47. /** Whether or not a response has been delivered for this request yet. */
  48. private boolean mResponseDelivered = false;
  49. // A cheap variant of request tracing used to dump slow requests.
  50. private long mRequestBirthTime = 0;
  51. /** Threshold at which we should log the request (even when debug logging is not enabled). */
  52. private static final long SLOW_REQUEST_THRESHOLD_MS = 3000;
  53. /** The retry policy for this request. */
  54. private RetryPolicy mRetryPolicy;
  55. /**
  56. * When a request can be retrieved from cache but must be refreshed from
  57. * the network, the cache entry will be stored here so that in the event of
  58. * a "Not Modified" response, we can be sure it hasn't been evicted from cache.
  59. */
  60. private Cache.Entry mCacheEntry = null;
  61. /** An opaque token tagging this request; used for bulk cancellation. */
  62. private Object mTag;
  63. /**
  64. * Creates a new request with the given URL and error listener. Note that
  65. * the normal response listener is not provided here as delivery of responses
  66. * is provided by subclasses, who have a better idea of how to deliver an
  67. * already-parsed response.
  68. */
  69. public Request(String url, Response.ErrorListener listener) {
  70. mUrl = url;
  71. mErrorListener = listener;
  72. setRetryPolicy(new DefaultRetryPolicy());
  73. }
  74. /**
  75. * Set a tag on this request. Can be used to cancel all requests with this
  76. * tag by {@link RequestQueue#cancelAll(Object)}.
  77. */
  78. public void setTag(Object tag) {
  79. mTag = tag;
  80. }
  81. /**
  82. * Returns this request's tag.
  83. * @see Request#setTag(Object)
  84. */
  85. public Object getTag() {
  86. return mTag;
  87. }
  88. /**
  89. * Sets the retry policy for this request.
  90. */
  91. public void setRetryPolicy(RetryPolicy retryPolicy) {
  92. mRetryPolicy = retryPolicy;
  93. }
  94. /**
  95. * Adds an event to this request's event log; for debugging.
  96. */
  97. public void addMarker(String tag) {
  98. if (MarkerLog.ENABLED) {
  99. mEventLog.add(tag, Thread.currentThread().getId());
  100. } else if (mRequestBirthTime == 0) {
  101. mRequestBirthTime = SystemClock.elapsedRealtime();
  102. }
  103. }
  104. /**
  105. * Notifies the request queue that this request has finished (successfully or with error).
  106. *
  107. * <p>Also dumps all events from this request's event log; for debugging.</p>
  108. */
  109. void finish(final String tag) {
  110. if (mRequestQueue != null) {
  111. mRequestQueue.finish(this);
  112. }
  113. if (MarkerLog.ENABLED) {
  114. final long threadId = Thread.currentThread().getId();
  115. if (Looper.myLooper() != Looper.getMainLooper()) {
  116. // If we finish marking off of the main thread, we need to
  117. // actually do it on the main thread to ensure correct ordering.
  118. Handler mainThread = new Handler(Looper.getMainLooper());
  119. mainThread.post(new Runnable() {
  120. @Override
  121. public void run() {
  122. mEventLog.add(tag, threadId);
  123. mEventLog.finish(this.toString());
  124. }
  125. });
  126. return;
  127. }
  128. mEventLog.add(tag, threadId);
  129. mEventLog.finish(this.toString());
  130. } else {
  131. long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;
  132. if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {
  133. VolleyLog.d("%d ms: %s", requestTime, this.toString());
  134. }
  135. }
  136. }
  137. /**
  138. * Associates this request with the given queue. The request queue will be notified when this
  139. * request has finished.
  140. */
  141. public void setRequestQueue(RequestQueue requestQueue) {
  142. mRequestQueue = requestQueue;
  143. }
  144. /**
  145. * Sets the sequence number of this request. Used by {@link RequestQueue}.
  146. */
  147. public final void setSequence(int sequence) {
  148. mSequence = sequence;
  149. }
  150. /**
  151. * Returns the sequence number of this request.
  152. */
  153. public final int getSequence() {
  154. if (mSequence == null) {
  155. throw new IllegalStateException("getSequence called before setSequence");
  156. }
  157. return mSequence;
  158. }
  159. /**
  160. * Returns the URL of this request.
  161. */
  162. public String getUrl() {
  163. return mUrl;
  164. }
  165. /**
  166. * Returns the cache key for this request. By default, this is the URL.
  167. */
  168. public String getCacheKey() {
  169. return getUrl();
  170. }
  171. /**
  172. * Annotates this request with an entry retrieved for it from cache.
  173. * Used for cache coherency support.
  174. */
  175. public void setCacheEntry(Cache.Entry entry) {
  176. mCacheEntry = entry;
  177. }
  178. /**
  179. * Returns the annotated cache entry, or null if there isn't one.
  180. */
  181. public Cache.Entry getCacheEntry() {
  182. return mCacheEntry;
  183. }
  184. /**
  185. * Mark this request as canceled. No callback will be delivered.
  186. */
  187. public void cancel() {
  188. mCanceled = true;
  189. }
  190. /**
  191. * Returns true if this request has been canceled.
  192. */
  193. public boolean isCanceled() {
  194. return mCanceled;
  195. }
  196. /**
  197. * Returns a list of extra HTTP headers to go along with this request. Can
  198. * throw {@link AuthFailureError} as authentication may be required to
  199. * provide these values.
  200. * @throws AuthFailureError In the event of auth failure
  201. */
  202. public Map<String, String> getHeaders() throws AuthFailureError {
  203. return Collections.emptyMap();
  204. }
  205. /**
  206. * Returns a Map of POST parameters to be used for this request, or null if
  207. * a simple GET should be used. Can throw {@link AuthFailureError} as
  208. * authentication may be required to provide these values.
  209. *
  210. * <p>Note that only one of getPostParams() and getPostBody() can return a non-null
  211. * value.</p>
  212. * @throws AuthFailureError In the event of auth failure
  213. */
  214. protected Map<String, String> getPostParams() throws AuthFailureError {
  215. return null;
  216. }
  217. /**
  218. * Returns which encoding should be used when converting POST parameters returned by
  219. * {@link #getPostParams()} into a raw POST body.
  220. *
  221. * <p>This controls both encodings:
  222. * <ol>
  223. * <li>The string encoding used when converting parameter names and values into bytes prior
  224. * to URL encoding them.</li>
  225. * <li>The string encoding used when converting the URL encoded parameters into a raw
  226. * byte array.</li>
  227. * </ol>
  228. */
  229. protected String getPostParamsEncoding() {
  230. return DEFAULT_POST_PARAMS_ENCODING;
  231. }
  232. public String getPostBodyContentType() {
  233. return "application/x-www-form-urlencoded; charset=" + getPostParamsEncoding();
  234. }
  235. /**
  236. * Returns the raw POST body to be sent.
  237. *
  238. * @throws AuthFailureError In the event of auth failure
  239. */
  240. public byte[] getPostBody() throws AuthFailureError {
  241. Map<String, String> postParams = getPostParams();
  242. if (postParams != null && postParams.size() > 0) {
  243. return encodePostParameters(postParams, getPostParamsEncoding());
  244. }
  245. return null;
  246. }
  247. /**
  248. * Converts <code>postParams</code> into an application/x-www-form-urlencoded encoded string.
  249. */
  250. private byte[] encodePostParameters(Map<String, String> postParams, String postParamsEncoding) {
  251. StringBuilder encodedParams = new StringBuilder();
  252. try {
  253. for (Map.Entry<String, String> entry : postParams.entrySet()) {
  254. encodedParams.append(URLEncoder.encode(entry.getKey(), postParamsEncoding));
  255. encodedParams.append('=');
  256. encodedParams.append(URLEncoder.encode(entry.getValue(), postParamsEncoding));
  257. encodedParams.append('&');
  258. }
  259. return encodedParams.toString().getBytes(postParamsEncoding);
  260. } catch (UnsupportedEncodingException uee) {
  261. throw new RuntimeException("Encoding not supported: " + postParamsEncoding, uee);
  262. }
  263. }
  264. /**
  265. * Set whether or not responses to this request should be cached.
  266. */
  267. public final void setShouldCache(boolean shouldCache) {
  268. mShouldCache = shouldCache;
  269. }
  270. /**
  271. * Returns true if responses to this request should be cached.
  272. */
  273. public final boolean shouldCache() {
  274. return mShouldCache;
  275. }
  276. /**
  277. * Priority values. Requests will be processed from higher priorities to
  278. * lower priorities, in FIFO order.
  279. */
  280. public enum Priority {
  281. LOW,
  282. NORMAL,
  283. HIGH,
  284. IMMEDIATE
  285. }
  286. /**
  287. * Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default.
  288. */
  289. public Priority getPriority() {
  290. return Priority.NORMAL;
  291. }
  292. /**
  293. * Returns the socket timeout in milliseconds per retry attempt. (This value can be changed
  294. * per retry attempt if a backoff is specified via backoffTimeout()). If there are no retry
  295. * attempts remaining, this will cause delivery of a {@link TimeoutError} error.
  296. */
  297. public final int getTimeoutMs() {
  298. return mRetryPolicy.getCurrentTimeout();
  299. }
  300. /**
  301. * Returns the retry policy that should be used for this request.
  302. */
  303. public RetryPolicy getRetryPolicy() {
  304. return mRetryPolicy;
  305. }
  306. /**
  307. * Mark this request as having a response delivered on it. This can be used
  308. * later in the request's lifetime for suppressing identical responses.
  309. */
  310. public void markDelivered() {
  311. mResponseDelivered = true;
  312. }
  313. /**
  314. * Returns true if this request has had a response delivered for it.
  315. */
  316. public boolean hasHadResponseDelivered() {
  317. return mResponseDelivered;
  318. }
  319. /**
  320. * Subclasses must implement this to parse the raw network response
  321. * and return an appropriate response type. This method will be
  322. * called from a worker thread. The response will not be delivered
  323. * if you return null.
  324. * @param response Response from the network
  325. * @return The parsed response, or null in the case of an error
  326. */
  327. abstract protected Response<T> parseNetworkResponse(NetworkResponse response);
  328. /**
  329. * Subclasses can override this method to parse 'networkError' and return a more specific error.
  330. *
  331. * <p>The default implementation just returns the passed 'networkError'.</p>
  332. *
  333. * @param volleyError the error retrieved from the network
  334. * @return an NetworkError augmented with additional information
  335. */
  336. protected VolleyError parseNetworkError(VolleyError volleyError) {
  337. return volleyError;
  338. }
  339. /**
  340. * Subclasses must implement this to perform delivery of the parsed
  341. * response to their listeners. The given response is guaranteed to
  342. * be non-null; responses that fail to parse are not delivered.
  343. * @param response The parsed response returned by
  344. * {@link #parseNetworkResponse(NetworkResponse)}
  345. */
  346. abstract protected void deliverResponse(T response);
  347. /**
  348. * Delivers error message to the ErrorListener that the Request was
  349. * initialized with.
  350. *
  351. * @param error Error details
  352. */
  353. public void deliverError(VolleyError error) {
  354. if (mErrorListener != null) {
  355. mErrorListener.onErrorResponse(error);
  356. }
  357. }
  358. /**
  359. * Our comparator sorts from high to low priority, and secondarily by
  360. * sequence number to provide FIFO ordering.
  361. */
  362. @Override
  363. public int compareTo(Request<T> other) {
  364. Priority left = this.getPriority();
  365. Priority right = other.getPriority();
  366. // High-priority requests are "lesser" so they are sorted to the front.
  367. // Equal priorities are sorted by sequence number to provide FIFO ordering.
  368. return left == right ?
  369. this.mSequence - other.mSequence :
  370. right.ordinal() - left.ordinal();
  371. }
  372. @Override
  373. public String toString() {
  374. return (mCanceled ? "[X] " : "[ ] ") + getUrl() + " " + getPriority() + " " + mSequence;
  375. }
  376. }