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).
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;
}
}