16772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru/* 26772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project 36772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 46772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License"); 56772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * you may not use this file except in compliance with the License. 66772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * You may obtain a copy of the License at 76772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 86772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * http://www.apache.org/licenses/LICENSE-2.0 96772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 106772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software 116772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS, 126772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * See the License for the specific language governing permissions and 146772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * limitations under the License. 156772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru */ 166772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 176772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Querupackage com.android.volley.toolbox; 186772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 196772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queruimport com.android.volley.Request; 206772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queruimport com.android.volley.Response; 216772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queruimport com.android.volley.VolleyError; 226772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 236772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queruimport java.util.concurrent.ExecutionException; 246772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queruimport java.util.concurrent.Future; 256772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queruimport java.util.concurrent.TimeUnit; 266772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queruimport java.util.concurrent.TimeoutException; 276772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 286772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru/** 296772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * A Future that represents a Volley request. 306772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 316772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * Used by providing as your response and error listeners. For example: 326772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * <pre> 336772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * RequestFuture<JSONObject> future = RequestFuture.newFuture(); 346772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * MyRequest request = new MyRequest(URL, future, future); 356772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 366772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * // If you want to be able to cancel the request: 376772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * future.setRequest(requestQueue.add(request)); 386772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 396772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * // Otherwise: 406772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * requestQueue.add(request); 416772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 426772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * try { 436772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * JSONObject response = future.get(); 446772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * // do something with response 456772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * } catch (InterruptedException e) { 466772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * // handle the error 476772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * } catch (ExecutionException e) { 486772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * // handle the error 496772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * } 506772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * </pre> 516772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * 526772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru * @param <T> The type of parsed response this future expects. 536772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru */ 546772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Querupublic class RequestFuture<T> implements Future<T>, Response.Listener<T>, 556772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru Response.ErrorListener { 566772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru private Request<?> mRequest; 576772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru private boolean mResultReceived = false; 586772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru private T mResult; 596772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru private VolleyError mException; 606772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 616772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public static <E> RequestFuture<E> newFuture() { 626772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return new RequestFuture<E>(); 636772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 646772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 656772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru private RequestFuture() {} 666772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 676772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public void setRequest(Request<?> request) { 686772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru mRequest = request; 696772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 706772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 716772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru @Override 726772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public synchronized boolean cancel(boolean mayInterruptIfRunning) { 736772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (mRequest == null) { 746772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return false; 756772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 766772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 776772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (!isDone()) { 786772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru mRequest.cancel(); 796772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return true; 806772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } else { 816772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return false; 826772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 836772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 846772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 856772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru @Override 866772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public T get() throws InterruptedException, ExecutionException { 876772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru try { 886772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return doGet(null); 896772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } catch (TimeoutException e) { 906772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru throw new AssertionError(e); 916772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 926772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 936772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 946772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru @Override 956772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public T get(long timeout, TimeUnit unit) 966772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru throws InterruptedException, ExecutionException, TimeoutException { 976772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return doGet(TimeUnit.MILLISECONDS.convert(timeout, unit)); 986772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 996772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1006772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru private synchronized T doGet(Long timeoutMs) 1016772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru throws InterruptedException, ExecutionException, TimeoutException { 1026772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (mException != null) { 1036772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru throw new ExecutionException(mException); 1046772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1056772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1066772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (mResultReceived) { 1076772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return mResult; 1086772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1096772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1106772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (timeoutMs == null) { 1116772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru wait(0); 1126772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } else if (timeoutMs > 0) { 1136772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru wait(timeoutMs); 1146772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1156772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1166772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (mException != null) { 1176772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru throw new ExecutionException(mException); 1186772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1196772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1206772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (!mResultReceived) { 1216772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru throw new TimeoutException(); 1226772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1236772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1246772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return mResult; 1256772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1266772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1276772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru @Override 1286772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public boolean isCancelled() { 1296772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru if (mRequest == null) { 1306772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return false; 1316772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1326772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return mRequest.isCanceled(); 1336772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1346772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1356772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru @Override 1366772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public synchronized boolean isDone() { 1376772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru return mResultReceived || mException != null || isCancelled(); 1386772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1396772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1406772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru @Override 1416772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public synchronized void onResponse(T response) { 1426772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru mResultReceived = true; 1436772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru mResult = response; 1446772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru notifyAll(); 1456772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1466772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 1476772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru @Override 1486772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru public synchronized void onErrorResponse(VolleyError error) { 1496772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru mException = error; 1506772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru notifyAll(); 1516772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru } 1526772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru} 1536772bce3d3322ccbcf6481545ffe895d5d401b39Jean-Baptiste Queru 154