diff options
Diffstat (limited to 'core/src/main/java/com/android/volley/ExecutorDelivery.java')
-rw-r--r-- | core/src/main/java/com/android/volley/ExecutorDelivery.java | 121 |
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(); + } + } + } +} |