Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit + Okhttp cancel operation not working

I am using retrofit in my application like this

 final OkHttpClient okHttpClient = new OkHttpClient();
 okHttpClient.interceptors().add(new YourInterceptor());

            final OkClient okClient = new OkClient(okHttpClient);
            Builder restAdapterBuilder = new RestAdapter.Builder();
            restAdapterBuilder.setClient(okClient).setLogLevel(LogLevel.FULL)
                    .setEndpoint("some url");
            final RestAdapter restAdapter = restAdapterBuilder.build();


public class YourInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        // TODO Auto-generated method stub
        Request request = chain.request();

        if (request != null) {
            Request.Builder signedRequestBuilder = request.newBuilder();
            signedRequestBuilder.tag("taggiventorequest");
            request = signedRequestBuilder.build();
            request.tag();
        }
        return chain.proceed(request);
    }
}

after sending request i am calling

okHttpClient.cancel("taggiventorequest");

but request is not cancelling i am getting the response from retrofit dont know why it is not cancelling my request

I need volley like cancelation retrofit

like image 860
SHASHIDHAR MANCHUKONDA Avatar asked Jul 17 '15 11:07

SHASHIDHAR MANCHUKONDA


People also ask

Which is better retrofit or OkHttp?

You should use retrofit if you are trying to map your server API inside your application (type-safing). Retrofit is just an API adapter wrapped over okHTTP. If you want to type safe and modularise the interaction code with your API, use retrofit.

What is the difference between retrofit and OkHttp?

OkHttp is a pure HTTP/SPDY client responsible for any low-level network operations, caching, requests and responses manipulation. In contrast, Retrofit is a high-level REST abstraction build on top of OkHttp. Retrofit is strongly coupled with OkHttp and makes intensive use of it.

What is interceptor in OkHttp?

Interceptors, according to the documentation, are a powerful mechanism that can monitor, rewrite, and retry the API call. So, when we make an API call, we can either monitor it or perform some tasks.

What is chain in interceptor?

The Chain object in retrofit is an implementation of the Chain of Responsibility design pattern, and each interceptor is a processing object which acquires the result of the previous interceptor through chain.


2 Answers

As Retrofit API Spec, Canceling request will be included in version 2.0.

cancel() is a no-op after the response has been received. In all other cases the method will set any callbacks to null (thus freeing strong references to the enclosing class if declared anonymously) and render the request object dead. All future interactions with the request object will throw an exception. If the request is waiting in the executor its Future will be cancelled so that it is never invoked.

For now, you can do it by creating custom callback class which implements on Callback from retrofit.

public abstract class CancelableCallback<T> implements Callback<T> {

    private boolean canceled;
    private T pendingT;
    private Response pendingResponse;
    private RetrofitError pendingError;

    public CancelableCallback() {
        this.canceled = false;
    }

    public void cancel(boolean remove) {
        canceled = true;
    } 

    @Override
    public void success(T t, Response response) {
        if (canceled) {
            return;
        }
        onSuccess(t, response);
    }

    @Override
    public void failure(RetrofitError error) {
        if (canceled) {
            return;
        }
        onFailure(error);
    }

    protected abstract void onSuccess(T t, Response response);

    protected abstract void onFailure(RetrofitError error);
}

MyApi.java,

private interface MyApi {
    @GET("/")
    void getStringList(Callback<List<String>> callback);
}

In Activity or Fragment,

RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint(Config.URL)
            .build();
MyApi service = restAdapter.create(MyApi.class);
CancelableCallback callback = new CancelableCallback<List<String>>() {
    @Override
    protected void onSuccess(List<String> stringList, Response response) {
        for (String str : stringList) {
            Log.i("Result : ", str);
        }
    }

    @Override
    protected void onFailure(RetrofitError error) {
        Log.e("Error : ", error.getMessage() + "");
    }
};

service.getStringList(callback);

To cancel your request, simple call

callback.cancel();

This is an simple example to cancel each request. You can handle (cancel, pause, resume) two or more request at the same time by creating callback manager class. Please take a look that comment for reference.

Hope it will be useful for you.

like image 148
Arkar Aung Avatar answered Oct 31 '22 17:10

Arkar Aung


The problem is that the request is completed, from the docs:

http://square.github.io/okhttp/javadoc/com/squareup/okhttp/OkHttpClient.html#cancel-java.lang.Object-

cancel

public OkHttpClient cancel(Object tag)

Cancels all scheduled or in-flight calls tagged with tag. Requests that are already complete cannot be canceled.

like image 28
isma3l Avatar answered Oct 31 '22 17:10

isma3l