I'm programming an application which communicates a http server.
I have both synchronized and asynchronized requests. I have a singleton which contains Volley RequestQueue for asynchronous requests. Now I want to implement a queue of synchronous requests like:
Request i -> ... -> Response i -> Request i+1 -> ... -> Response i+1
but not:
Request i -> Request i+1 -> ... -> Response i -> Response i+1
I have read this topic: Can I do a synchronous request with volley?
I want to inject different Listener and ErrorListener (depends on request type). So I added new objects of Listener and ErrorListener as variables in RequestFuture class.
public class RequestFuture<T> implements Future<T>, Response.Listener<T>, Response.ErrorListener {
...
Response.Listener mListener;
Response.ErrorListener mErrorListener;
...
}
But what I truly want to do is a queue of async requests. How can I do it with Volley?
I wonder whether I continue with Volley or HTTPRequestExecutor(has been deprecated)?
Any feedback is much appreciated, thanks.
Honestly, i dont use this method anymore. It would be better to use Callback instead of sync requests queue, it'll make your code easier to update, easier to other dev to understand. Do not hesitate to add an extra Callback parametre, ex: request_1 (callback_1, ...), callback_1 calls request_2(callback_2,...) in listener events >> etc.
Below is the old answer:
I post my solution here (it's not very clean but it's my work so far):
- Using the same Volley Request Queue for both async and sync requests.
- Creating new class SyncRequestLoader implements Response.ErrorListener, Response.Listener.
My class:
public class SyncRequestLoader implements Response.ErrorListener, Response.Listener {
public final String TAG = "SyncRequestLoader";
private RequestQueue mRequestQueue;
private Response.Listener mListener;
private Response.ErrorListener mErrorListener;
private LinkedList<StringRequest> mSyncRequests;
private Handler.Callback mCallback;
public SyncRequestLoader(RequestQueue mRequestQueue) {
this.mRequestQueue = mRequestQueue;
mSyncRequests = new LinkedList<>();
}
synchronized public void add(StringRequest request) {
mSyncRequests.add(request);
if (size() == 1)
transceive();
}
@Override
synchronized public void onResponse(Object response) {
mListener.onResponse(response);
//do anything here if u want
removeCompletedRequest();
continueIfPossible();
}
@Override
synchronized public void onErrorResponse(VolleyError error) {
mErrorListener.onErrorResponse(error);
//do anything here if u want
removeCompletedRequest();
continueIfPossible();
}
synchronized private void transceive() {
StringRequest request = mSyncRequests.getFirst();
mListener = request.getListener();
mErrorListener = request.getErrorListener();
StringRequest new_request = new StringRequest(request.getUrl(), this, this);
mRequestQueue.add(new_request);
}
synchronized private void removeCompletedRequest() {
mSyncRequests.removeFirst();
}
synchronized private void continueIfPossible() {
if (size() > 0)
transceive();
else if (isOnCallback())
mCallback.handleMessage(Message.obtain(null, 1));
}
public boolean isOnCallback() {
return (mCallback != null);
}
public void setCallback(Handler.Callback callback) {
this.mCallback = callback;
}
}
I'm using SyncRequestLoader mCallback for notify that Sync Request Queue has finished. I store all sync request in a Linkedlist then add into volley queue one by one. Each request will be injected to Volley request queue since we got the response of previous request. I "tricked" here by making a new request with local variable mListener and mErrorListener, you can see I parse the response to the "true" listeners after.