Android - Volley - synchronous and asynchronous http requests
Asked Answered
K

1

2

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.

Kinghood answered 28/8, 2015 at 10:27 Comment(0)
K
0

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.

Kinghood answered 31/8, 2015 at 14:6 Comment(6)
Anh, this looks like what I've been looking for. Would you mind updating your answer w/ the most recent code?Henebry
For example, I think "size()" should be "mSyncRequests.size()" ?Henebry
and in transceive() what is "request.getListener()" ?Henebry
and I don't understand anything about: mCallback.handleMessage( Message.obtain( null, 1 )Henebry
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.Kinghood
mCallback.handleMessage( Message.obtain( null, 1 ) is where you send a signal to somewhere to say "I did get a response". This mCallback is that somewhere. Your remark about mSyncRequests.size() is correct :)Kinghood

© 2022 - 2024 — McMap. All rights reserved.