aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/java/com/android/volley/ExecutorDelivery.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/com/android/volley/ExecutorDelivery.java')
-rw-r--r--core/src/main/java/com/android/volley/ExecutorDelivery.java121
1 files changed, 121 insertions, 0 deletions
diff --git a/core/src/main/java/com/android/volley/ExecutorDelivery.java b/core/src/main/java/com/android/volley/ExecutorDelivery.java
new file mode 100644
index 0000000..fd992f9
--- /dev/null
+++ b/core/src/main/java/com/android/volley/ExecutorDelivery.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.volley;
+
+import android.os.Handler;
+import java.util.concurrent.Executor;
+
+/** Delivers responses and errors. */
+public class ExecutorDelivery implements ResponseDelivery {
+ /** Used for posting responses, typically to the main thread. */
+ private final Executor mResponsePoster;
+
+ /**
+ * Creates a new response delivery interface.
+ *
+ * @param handler {@link Handler} to post responses on
+ */
+ public ExecutorDelivery(final Handler handler) {
+ // Make an Executor that just wraps the handler.
+ mResponsePoster =
+ new Executor() {
+ @Override
+ public void execute(Runnable command) {
+ handler.post(command);
+ }
+ };
+ }
+
+ /**
+ * Creates a new response delivery interface, mockable version for testing.
+ *
+ * @param executor For running delivery tasks
+ */
+ public ExecutorDelivery(Executor executor) {
+ mResponsePoster = executor;
+ }
+
+ @Override
+ public void postResponse(Request<?> request, Response<?> response) {
+ postResponse(request, response, null);
+ }
+
+ @Override
+ public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
+ request.markDelivered();
+ request.addMarker("post-response");
+ mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
+ }
+
+ @Override
+ public void postError(Request<?> request, VolleyError error) {
+ request.addMarker("post-error");
+ Response<?> response = Response.error(error);
+ mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
+ }
+
+ /** A Runnable used for delivering network responses to a listener on the main thread. */
+ @SuppressWarnings("rawtypes")
+ private static class ResponseDeliveryRunnable implements Runnable {
+ private final Request mRequest;
+ private final Response mResponse;
+ private final Runnable mRunnable;
+
+ public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
+ mRequest = request;
+ mResponse = response;
+ mRunnable = runnable;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ // NOTE: If cancel() is called off the thread that we're currently running in (by
+ // default, the main thread), we cannot guarantee that deliverResponse()/deliverError()
+ // won't be called, since it may be canceled after we check isCanceled() but before we
+ // deliver the response. Apps concerned about this guarantee must either call cancel()
+ // from the same thread or implement their own guarantee about not invoking their
+ // listener after cancel() has been called.
+
+ // If this request has canceled, finish it and don't deliver.
+ if (mRequest.isCanceled()) {
+ mRequest.finish("canceled-at-delivery");
+ return;
+ }
+
+ // Deliver a normal response or error, depending.
+ if (mResponse.isSuccess()) {
+ mRequest.deliverResponse(mResponse.result);
+ } else {
+ mRequest.deliverError(mResponse.error);
+ }
+
+ // If this is an intermediate response, add a marker, otherwise we're done
+ // and the request can be finished.
+ if (mResponse.intermediate) {
+ mRequest.addMarker("intermediate-response");
+ } else {
+ mRequest.finish("done");
+ }
+
+ // If we have been provided a post-delivery runnable, run it.
+ if (mRunnable != null) {
+ mRunnable.run();
+ }
+ }
+ }
+}