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 17package com.android.volley; 18 19import android.os.Handler; 20 21import java.util.concurrent.Executor; 22 23/** 24 * Delivers responses and errors. 25 */ 26public class ExecutorDelivery implements ResponseDelivery { 27 /** Used for posting responses, typically to the main thread. */ 28 private final Executor mResponsePoster; 29 30 /** 31 * Creates a new response delivery interface. 32 * @param handler {@link Handler} to post responses on 33 */ 34 public ExecutorDelivery(final Handler handler) { 35 // Make an Executor that just wraps the handler. 36 mResponsePoster = new Executor() { 37 @Override 38 public void execute(Runnable command) { 39 handler.post(command); 40 } 41 }; 42 } 43 44 /** 45 * Creates a new response delivery interface, mockable version 46 * for testing. 47 * @param executor For running delivery tasks 48 */ 49 public ExecutorDelivery(Executor executor) { 50 mResponsePoster = executor; 51 } 52 53 @Override 54 public void postResponse(Request<?> request, Response<?> response) { 55 postResponse(request, response, null); 56 } 57 58 @Override 59 public void postResponse(Request<?> request, Response<?> response, Runnable runnable) { 60 request.markDelivered(); 61 request.addMarker("post-response"); 62 mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable)); 63 } 64 65 @Override 66 public void postError(Request<?> request, VolleyError error) { 67 request.addMarker("post-error"); 68 Response<?> response = Response.error(error); 69 mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null)); 70 } 71 72 /** 73 * A Runnable used for delivering network responses to a listener on the 74 * main thread. 75 */ 76 @SuppressWarnings("rawtypes") 77 private class ResponseDeliveryRunnable implements Runnable { 78 private final Request mRequest; 79 private final Response mResponse; 80 private final Runnable mRunnable; 81 82 public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) { 83 mRequest = request; 84 mResponse = response; 85 mRunnable = runnable; 86 } 87 88 @SuppressWarnings("unchecked") 89 @Override 90 public void run() { 91 // If this request has canceled, finish it and don't deliver. 92 if (mRequest.isCanceled()) { 93 mRequest.finish("canceled-at-delivery"); 94 return; 95 } 96 97 // Deliver a normal response or error, depending. 98 if (mResponse.isSuccess()) { 99 mRequest.deliverResponse(mResponse.result); 100 } else { 101 mRequest.deliverError(mResponse.error); 102 } 103 104 // If this is an intermediate response, add a marker, otherwise we're done 105 // and the request can be finished. 106 if (mResponse.intermediate) { 107 mRequest.addMarker("intermediate-response"); 108 } else { 109 mRequest.finish("done"); 110 } 111 112 // If we have been provided a post-delivery runnable, run it. 113 if (mRunnable != null) { 114 mRunnable.run(); 115 } 116 } 117 } 118} 119