使用loopj Android异步Http客户端同步发起请求

5

我正在尝试使用loopj的setUseSynchronousMode功能,在某些情况下等待http调用的结果才能继续。我尝试了以下方法:

    AsyncHttpResponseHandler responseHandler = new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] response) {
            Log.d("TEST", "Got results");
        }
    };

    AsyncHttpClient client = new AsyncHttpClient();
    responseHandler.setUseSynchronousMode(true);
    client.get("http://www.google.com", responseHandler);
    Log.d("TEST", "Don't want to get here until after getting results");

但是结果是:
07-11 19:48:05.631 D/TEST﹕ Don't want to get here until after getting results
07-11 19:48:05.814 D/TEST﹕ Got results

我是否误解了setUseSynchronousMode的作用?

无论同步模式是否这样做,这都不是你应该做的事情。它会冻结整个UI线程并使手机无响应。HTTP请求必须在另一个线程上完成,这就是为什么有这个要求的原因,请不要试图绕过它。 - Gabe Sechan
3
@Gabe Sechan,我没有在 UI 线程上调用它。 - Edwin Evans
2个回答

5

你应该使用SyncHttpClient而不是AsyncHttpClientsetUseSynchronousMode对于AsyncHttpClient没有预期的效果。


你能分享一段示例代码吗?SyncHttpClient似乎不会阻塞它正在运行的线程,这使我无法取消请求。 - Sufian
首先,我最终使用了带有回调函数的AsyncHttpClient,因为这确实是一种更清晰的方法,所以您可能需要再考虑一下是否要这样做。但是我认为如果您使用SyncHttpClient(也许需要调用responseHandler.setUseSynchronousMode(true)),它也应该可以工作。虽然我不会对它不支持取消请求感到惊讶。 - Edwin Evans

2
为了拥有可以取消的同步版本的AsyncHttpClient,我在主线程上处理所有操作。之前我是在AsyncTask中运行它,一旦调用了AsyncHttpClient.post()AsyncTask就会结束,我无法跟踪AsyncHttpClient实例。

SyncHttpClient不允许我取消上传,所以我知道必须使用AsyncHttpClient并进行适当的更改。

以下是我用于上传文件的类,它使用AsyncHttpClient并允许取消:

public class AsyncUploader {
    private String mTitle;
    private String mPath;
    private Callback mCallback;

    public void AsyncUploader(String title, String filePath, MyCallback callback) {
        mTitle = title;
        mPath = filePath;
        mCallback = callback;
    }

    public void startTransfer() {
        mClient = new AsyncHttpClient();
        RequestParams params = new RequestParams();
        File file = new File(mPath);
        try {
            params.put("title", mTitle);
            params.put("video", file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        mClient.setTimeout(50000);
        mClient.post(mContext, mUrl, params, new ResponseHandlerInterface() {
            @Override
            public void sendResponseMessage(HttpResponse response) throws IOException {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream instream = entity.getContent();
                    // TODO convert instream to JSONObject and do whatever you need to
                    mCallback.uploadComplete();
                }
            }
            @Override
            public void sendProgressMessage(int bytesWritten, int bytesTotal) {
                mCallback.progressUpdate(bytesWritten, bytesTotal);
            }
            @Override
            public void sendFailureMessage(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                mCallback.failedWithError(error.getMessage());
            }
        });
    }

    /**
    * Cancel upload by calling this method
    */
    public void cancel() {
        mClient.cancelAllRequests(true);
    }
}

这是运行它的方法:
AsyncUploader uploader = new AsyncUploader(myTitle, myFilePath, myCallback);
uploader.startTransfer();
/* Transfer started */
/* Upon completion, myCallback.uploadComplete() will be called */

要取消上传,只需调用cancel()方法,如下所示:

uploader.cancel();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接