Skip to content

Instantly share code, notes, and snippets.

@rhexgomez
Created August 3, 2016 08:26
Show Gist options
  • Save rhexgomez/c49064f0dde7422b507a15d4d11ff1df to your computer and use it in GitHub Desktop.
Save rhexgomez/c49064f0dde7422b507a15d4d11ff1df to your computer and use it in GitHub Desktop.
The reusable implementation of Future<T> Blocking callback in Android Volley
/*
* Copyright 2016 Elmar Rhex Gomez.
*
* 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.
*/
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ReusableFuture<T> implements Future<T>, Response.Listener<T>,
Response.ErrorListener {
private Request<?> mRequest;
private boolean mResultReceived = false;
private T mResult;
private VolleyError mException;
public static <E> ReusableFuture<E> newFuture() {
return new ReusableFuture<E>();
}
private ReusableFuture() {
}
public void setRequest(Request<?> request) {
mRequest = request;
}
@Override
public synchronized boolean cancel(boolean mayInterruptIfRunning) {
if (mRequest == null) {
return false;
}
if (!isDone()) {
mRequest.cancel();
return true;
} else {
return false;
}
}
@Override
public T get() throws InterruptedException, ExecutionException {
try {
return doGet(null);
} catch (TimeoutException e) {
throw new AssertionError(e);
}
}
@Override
public T get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return doGet(TimeUnit.MILLISECONDS.convert(timeout, unit));
}
private synchronized T doGet(Long timeoutMs)
throws InterruptedException, ExecutionException, TimeoutException {
if (mException != null) {
throw new ExecutionException(mException);
}
if (mResultReceived) {
T res = mResult;
reset();
return res;
}
if (timeoutMs == null) {
wait(0);
} else if (timeoutMs > 0) {
wait(timeoutMs);
}
if (mException != null) {
throw new ExecutionException(mException);
}
if (!mResultReceived) {
throw new TimeoutException();
}
T res = mResult;
reset();
return res;
}
public T getReliableResponse() throws ExecutionException, InterruptedException {
T response = null;
while (!mResultReceived) {
try {
response = get(50, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
// Do nothing
}
}
return response;
}
@Override
public boolean isCancelled() {
if (mRequest == null) {
return false;
}
return mRequest.isCanceled();
}
@Override
public synchronized boolean isDone() {
return mResultReceived || mException != null || isCancelled();
}
@Override
public synchronized void onResponse(T response) {
mResultReceived = true;
mResult = response;
notifyAll();
}
@Override
public synchronized void onErrorResponse(VolleyError error) {
mException = error;
notifyAll();
}
private void reset() {
mRequest = null;
mResultReceived = false;
mResult = null;
mException = null;
}
}
@rhexgomez
Copy link
Author

rhexgomez commented Aug 3, 2016

Usecase:

 ReusableFuture<JSONObject> listener = new ReusableFuture.newFuture();
 JsonObjectRequest uploadRequest = new JsonObjectRequest(....... , listener, listener);

 // Your singleton implementation
 VolleySingleton.init(mContext).requestQueue().add(uploadRequest);

 try {
    JSONObject blockingResponse = listener.getReliableResponse();
     // Do something here or reuse the class again.
 } catch (ExecutionException e) {
 } catch (InterruptedException e) {
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment