5

I'm trying to use setUseSynchronousMode on loopj to wait for results of http call before continuing in one case. I tried:

    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");

But the result is:

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

Am I misunderstanding what setUseSynchronousMode should do?

Edwin Evans
  • 2,726
  • 5
  • 34
  • 47
  • Whether that's what synchronous mode does or not, its NOT anything you should ever do. It will freeze up your entire UI thread and make the phone unresponsive. There's a reason why HTTP requests have to be done on another thread, don't try to work around it. – Gabe Sechan Jul 12 '14 at 06:48
  • 3
    @Gabe Sechan, I'm not calling it on a UI thread. – Edwin Evans Jul 12 '14 at 16:09

2 Answers2

5

You should have used SyncHttpClient instead of AsyncHttpClient. setUseSynchronousMode doesn't have the desired effect for AsyncHttpClient.

Zapnologica
  • 22,170
  • 44
  • 158
  • 253
Edwin Evans
  • 2,726
  • 5
  • 34
  • 47
  • Could you share a sample code? `SyncHttpClient` doesn't seem to block the thread it is running on and this stops me from cancelling the request. – Sufian Oct 27 '14 at 05:40
  • First off, I did end up using AsyncHttpClient with callback as this really was a cleaner approach so you may want to think some more about doing it that way. But I think if you use SyncHttpClient (perhaps need to call responseHandler.setUseSynchronousMode(true)) also it should work. I'm not surprised it doesn't support canceling the request though. – Edwin Evans Oct 27 '14 at 15:20
2

To have synchronous version of AsyncHttpClient with an ability to cancel it, I do everything on the main thread. Previously I was running it in AsyncTask and as soon as AsyncHttpClient.post() was called, the AsyncTask would finish and I was unable to keep track the AsyncHttpClient instance.

SyncHttpClient didn't allow me to cancel the uploading so I knew I had to use AsyncHttpClient and make appropriate changes.

Following is my class to upload a file which uses AsyncHttpClient and allows cancellation:

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

This is how you can run it:

AsyncUploader uploader = new AsyncUploader(myTitle, myFilePath, myCallback);
uploader.startTransfer();
/* Transfer started */
/* Upon completion, myCallback.uploadComplete() will be called */

To cancel the upload, just call cancel() like:

uploader.cancel();
Sufian
  • 6,405
  • 16
  • 66
  • 120