Morozov
Morozov

Reputation: 5260

How to Cancel Retrofit request

I scroll through the official documentation of Retrofit and decided to implement something like this in my project, so that the user always has the option to cancel the download file and everything would work correctly. Implement appropriate methods, where the failure to prescribe the following:

service.upload1(file1, str, stringMap, new Callback<ImageUpload>() {
            @Override
            public void success(final ImageUpload imageUpload, Response response) {
                mRecyclerView.post(new Runnable() {
                    @Override
                    public void run() {
                        ...
                });
            }

            @Override
            public void failure(RetrofitError error) {
                if (error.isCanceled()) {
                    Log.e(TAG, "request is cancelled");
                } else {
                    Log.e(TAG, "other larger issue, i.e. no network connection?");
                }
            }

But underlines in red isCanceled in failure method. I do not understand what's the problem, because this method we initially proposed class Call(perhaps because swears at me instead of class Call is RetrofitError?) Please tell me how to fix. I use retrofit 1.9, and i don't need go on retrofit 2.

Upvotes: 21

Views: 39566

Answers (4)

Amit Tiwari
Amit Tiwari

Reputation: 3692

error.isCanceled() does not seem to be there in Retrofit as far as I remember. If you want to be able to cancel a request, you can either switch to Retrofit 2 where they have a call.cancel() method or in the current version of Retrofit, you could extent the Callback class to create your own class CancellableCallback like this:

public class CancellableCallback<T> implements Callback<T> {

    private Callback<T> callback;

    private boolean canceled;

    private CancellableCallback() {}

    public CancellableCallback(Callback<T> callback) {
        this.callback = callback;
        canceled = false;
    }

    public void cancel() {
        canceled = true;
        callback = null;
    }

    @Override
    public void success(T o, Response response) {
        if (!canceled) {
            callback.success(o, response);
        }
    }

    @Override
    public void failure(RetrofitError error) {
        if (!canceled) {
            callback.failure(error);
        }
    }
}

Edit

You can then use it like this:

CancellableCallback callback = new Callback<ImageUpload>() {
            @Override
            public void success(final ImageUpload imageUpload, Response response) {
                mRecyclerView.post(new Runnable() {
                    @Override
                    public void run() {
                        ...
                });
            }

            @Override
            public void failure(RetrofitError error) {

            }
    };

service.upload1(file1, str, stringMap, callback);

And then cancel it like this:

if (some condition && callback != null) {
    callback.cancel();
}

Upvotes: 26

Pratik Butani
Pratik Butani

Reputation: 62419

You can Cancel Request like:

// something happened, for example: user clicked cancel button
service.cancel();  

and get callback of Cancel like:

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
       if (call.isCanceled()) {
           Log.e(TAG, "request was cancelled");
       }
       else {
           Log.e(TAG, "other larger issue, i.e. no network connection?");
       }
}

You can check here for more.

Upvotes: 14

Devansh Kumar
Devansh Kumar

Reputation: 1562

You should switch to retrofit2 , and then write something like this -

service.upload1(file1, str, stringMap, new Callback<ImageUpload>() {
        @Override
        public void onResponse(Call<ImageUpload> call, Response<Topics> response) {

            //retrieve your resbonse body here like this -
            //   ImageUpload imageUpload = response.body();
            mRecyclerView.post(new Runnable() {
                @Override
                public void run() {
                    ...
            });
        }

        @Override
        public void onFailure(Call<ImageUpload> call, Throwable t) {
            if (call.isCanceled()) {
                Log.e(TAG, "request is cancelled");
            } else {
                Log.e(TAG, "other larger issue, i.e. no network connection?");
            }
        }

Upvotes: 1

Marius Kaunietis
Marius Kaunietis

Reputation: 704

You should use Retrofit 2 for that and change interface method signature to return a Call object. To do a request, you call enqueue method. After that, you can call cancel method to cancel the request.

Upvotes: 2

Related Questions