How to use loopJ SyncHttpClient for synchronous ca

2019-03-17 00:46发布

问题:

I have been stuck on this for two days now, finally decided to post here.

I see loopj library being used for Async Calls and with lots of examples and explanations.

But since I cannot use async calls in IntentSerive in Android I am forced to use SyncHttpClient, but it does not seem to work as only the onFailure callback is called when I use SyncHttpClient.

There are no examples of using SyncHttpClient also in the documentation.

This issue is also discussed here.

So can someone give the right way to do it?

回答1:

You do it the same way as async http client, you provide your handler that implements ResponseHandlerInterface, but now the request will be executed within the same thread. You can easily check it yourself by setting the debugger to the next statement after your sync http client call and see that debugger will hit this statement after your onSuccess / onFailure callback executed. In case of async debugger will hit this even before your onStart method, cause it is going to be executed in a separate thread.

Example:

mSyncClient.post("http://example.com", params, new JsonHttpResponseHandler() {
            @Override
            public void onStart() {
                // you can do something here before request starts                    
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                // success logic here
            }


            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject errorResponse) {
               // handle failure here
            }

        });

 // the statements after this comment line will be executed after onSuccess (or onFailure ) callback.


回答2:

You can use SyncHttpClient but you won't have the option to cancel it. I made a class which uses AsyncHttpClient to upload file but it has an edge over the SyncHttpClient class - it allows cancellation. I've already posted the code in other thread.

Code from the same thread:

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