【问题标题】:How can I make two simultaneous Http Requests with Loopj AsyncHttpLibrary in Android?如何在 Android 中使用 Loopj AsyncHttpLibrary 同时发出两个 Http 请求?
【发布时间】:2013-05-16 12:58:13
【问题描述】:

我将Loopj AsyncHttpLibrary 用于Android 应用程序。我的目的是显示一个包含一些问题和相应答案的页面。我正在编写的 Rest API 在不同的端点提供问题和答案:

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

我现在正在做的是为“问题”发出一个异步 http 请求,然后在第一个请求的成功回调中,我执行第二个请求以获取“答案”。这是我清理后的代码:

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

        MyApiClient.getAnswers(docId, new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(JSONObject answersResponse) {

                .... Do stuff ....

            }
        });
    }
});

其中 MyApiClient 是库文档中推荐的 AsyncHttpLibrary 的静态包装器,如下所示:

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

有没有一种方法可以启动两个请求而无需等待另一个请求执行? 我还需要能够在相同的上下文中使用两个 http 结果(填充 ui)。

【问题讨论】:

  • 有很多方法可以启动两个请求,而无需等待另一个请求执行。你熟悉 AsyncTask 类吗?还是线程?如果我猜对了。
  • 我不熟悉 AsyncTask 类,但我使用过 Threads。我首先尝试构建一个在不同线程上运行的服务,它处理网络请求,但结果太复杂了,所以我最终使用了 loopj 的库。

标签: java android httprequest loopj


【解决方案1】:

经过一番挣扎,我发现在我的活动课上保持网络操作状态并不难。我最终使用了两个布尔变量:“fetchedQuestions”和“fetchedAnswers”,它们在初始化网络请求之前被重置为“false”。两个请求同时发送,在它们的成功方法中,我检查另一个请求是否已完成。

这里是代码(使用 Loopj AsyncHttpClient 库)

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"
    }     

}

其中 MyApiClient 被定义为

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

【讨论】:

  • 有效吗?在调用 if 语句之前,标志可能不会更改。也许将其更改为 while(flag) 有效?
  • 是的,它有效。两个“if”块都驻留在异步 onSuccess 函数中,一旦查询完成,它们就会被调用。他们检查其他查询是否在他们之前完成。
【解决方案2】:

希望这会有所帮助:

public class SampleActivity extends Activity{

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new GetQuestionsThread().execute();
        new GetAnswersThread().execute();
    }

    public class GetQuestionsThread extends AsyncTask<Void, Void, String> {
        public GetQuestionsThread() {

        }

        @Override
        protected String doInBackground(Void... params) {

            //make post

            return request;
        }

        @Override
        protected void onPostExecute(LString result) {
            // do something with result
        }
    }

    public class GetAnswersThread extends AsyncTask<Void, Void, String> {
        public GetAnswersThread() {

        }

        @Override
        protected String doInBackground(Void... params) {
            //make post
            return request;
        }

        @Override
        protected void onPostExecute(LString result) {
            // do something with result
        }
    }

}

【讨论】:

  • 非常感谢您的回复。我试图让这种方法工作,但响应不在同一上下文中,因此无法判断当我得到“答案”时是否提取了“问题”,反之亦然。由于我在标题中提到了 Loopj 的库,因此我使用该库使用我的解决方案更新了线程。
猜你喜欢
  • 2015-02-15
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 2023-02-06
相关资源
最近更新 更多