Search code examples
javaandroidhttprequestloopj

How can I make two simultaneous Http Requests with Loopj AsyncHttpLibrary in Android?


I am using Loopj AsyncHttpLibrary for an android application. My purpose is to show a page containing some questions and corresponding answers. The Rest API, that I am coding against, serves questions and answers at different endpoints as:

http://example.com/docs/{id}/questions
http://example.com/docs/{id}/answers

What I'm doing right now is to make an async http request for "questions", then in the success callback of the first request, I do the second request to fetch "answers". Here is my cleaned code:

MyApiClient.getQuestions(docId, new JsonHttpResponseHandler() {
    @Override
    public void onSuccess(JSONObject questionsResponse) {

        MyApiClient.getAnswers(docId, new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(JSONObject answersResponse) {

                .... Do stuff ....

            }
        });
    }
});

where MyApiClient is a static wrapper for the AsyncHttpLibrary as recommended in the library's documentation, it looks like this:

public class MyApiClient {
    private static final String BASE_URL = "http://example.com/";

    private static AsyncHttpClient client = new AsyncHttpClient();

    public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
        client.get(getAbsoluteUrl(url), params, responseHandler);
    }

    public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
        client.post(getAbsoluteUrl(url), params, responseHandler);
    }

    public static void getQuestions(long docId, AsyncHttpResponseHandler responseHandler) {
        get("docs/" + String.valueOf(docId) + "/questions" , null, responseHandler);
    }

    public static void getAnswers(long docId, AsyncHttpResponseHandler responseHandler){
        get("docs/" + String.valueOf(docId) + "/answers" , null, responseHandler);
    }

    private static String getAbsoluteUrl(String relativeUrl) {
        return BASE_URL + relativeUrl;
    }
}

Is there a way to start both requests without one waiting for the other to execute? I also need to be able use both http results in the same context (populating ui).


Solution

  • After some struggling, I found it was not that hard to hold a state of the network operations in my activity class. I ended up using two boolean vars: "fetchedQuestions" and "fetchedAnswers", which are reset to 'false ' before initializing network requests. Both requests are sent simultaneously and in their success methods, I check if the other request is finalized or not.

    Here is the code (using Loopj AsyncHttpClient library)

    public class MyActivity extends Activity {
    
        private boolean fetchedQuestions;
        private boolean fetchedAnswers;
    
        private JSONObject questions;
        private JSONObject answers;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            refresh();
        }
    
        private void refresh(){
    
            fetchedQuestions = false;
            fetchedAnswers = false;
    
            long docId = 1;
    
            MyApiClient.getQuestions(docId, new JsonHttpResponseHandler() {
                @Override
                public void onSuccess(JSONObject questionsResponse) {
                    questions = questionsResponse;  
                    fetchedQuestions = true;
                    if (fetchedAnswers)
                        populatePage();
    
                }
            });
    
            MyApiClient.getAnswers(docId, new JsonHttpResponseHandler() {
                @Override
                public void onSuccess(JSONObject answersResponse) {
                    answers = answersResponse;  
                    fetchedAnswers = true;
                    if (fetchedQuestions)
                        populatePage();
    
                }
            });
        }
    
        private void populatePage(){
            // do stuff with "questions" and "answers"
        }     
    
    }
    

    where MyApiClient is defined as

    public class MyApiClient {
        private static final String BASE_URL = "http://example.com/";
    
        private static AsyncHttpClient client = new AsyncHttpClient();
    
        public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
            client.get(getAbsoluteUrl(url), params, responseHandler);
        }
    
        public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
            client.post(getAbsoluteUrl(url), params, responseHandler);
        }
    
        public static void getQuestions(long docId, AsyncHttpResponseHandler responseHandler) {
            get("docs/" + String.valueOf(docId) + "/questions" , null, responseHandler);
        }
    
        public static void getAnswers(long docId, AsyncHttpResponseHandler responseHandler){
            get("docs/" + String.valueOf(docId) + "/answers" , null, responseHandler);
        }
    
        private static String getAbsoluteUrl(String relativeUrl) {
            return BASE_URL + relativeUrl;
        }
    }