24

I have rest api.

@Get("/serveraction")
public Observable<String> myRequest(@Query("Data") String data);

I know, that okhttp has canceling functionality(by request object, by tag), but don't know how use it with retrofit and rxjava. What is the best way to realize canceling mechanism for network tasks with retrofit and rxjava?

zella
  • 4,645
  • 6
  • 35
  • 60

2 Answers2

38

You can use the standard RxJava2 cancelling mechanism Disposable.

Observable<String> o = retrofit.getObservable(..);
Disposable d = o.subscribe(...);

// later when not needed
d.dispose();

Retrofit RxJava call adapter will redirect this to okHttp's cancel.

RxJava1: https://github.com/square/retrofit/blob/46dc939a0dfb470b3f52edc88552f6f7ebb49f42/retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/CallArbiter.java#L50-L53

RxJava2: https://github.com/square/retrofit/blob/46dc939a0dfb470b3f52edc88552f6f7ebb49f42/retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/CallEnqueueObservable.java#L92-L95

Sergii Pechenizkyi
  • 22,227
  • 7
  • 60
  • 71
  • FYI: I'm pretty sure [ObservableCallAdapterFactory](https://github.com/square/retrofit/blob/master/retrofit-adapters/rxjava/src/main/java/retrofit/ObservableCallAdapterFactory.java) in retrofit-adpaters is going to be part of as of yet unreleased Retrofit 2.0 and isn't currently part of Retrofit 1.9. Unsubscribing as described above by @Sergii will still achieve the effect of your subscriber not getting the response, but how it is cancelled internally is less clean and you may see some thread interrupted exceptions (but they won't crash your app). – Nick Jul 31 '15 at 16:33
  • the link is dead – zella Feb 04 '19 at 17:28
5

The chosen answer is for Rx Java 1 and is not valid for RxJava2. For the latter, you can use Disposable. Follow this:

  1. Define CompositeDisposable compositeDisposable=new CompositeDisposable() as a field in your Activity or Fragment in class.
  2. Define the api using Retrofit 2 as something like this:

    public Observable<YourPojo> callApiWithRetrofit() {
        return getService(YourApiService.class).callApi();
    }
    
  3. Define Disposableand add it to the compositeDisposable instance:

    Disposable disposable = callApiWithRetrofit().subscribeOn(Schedulers.io()).observeOn(
            AndroidSchedulers.mainThread()).subscribeWith(
            new DisposableObserver<List<YourPojo>>() {
                @Override
                protected void onStart() {
                    super.onStart();
                }
    
                @Override
                public void onNext(@NonNull List<AlertAssetDTO> listResponse) {
    
                }
    
                @Override
                public void onError(@NonNull Throwable e) {
    
                }
    
                @Override
                public void onComplete() {
    
                }
            });
    mCompositeDisposable.add(disposable);
    
  4. Wherever you want the connection to be cancelled (e.g. onDestroy() method of your Activity or onDestroyView() of your Fragment) call mCompositeDisposable.clear();

Multiple disposables may be added to the CompostieDisposable above this way.

Shmuser
  • 202
  • 2
  • 10
Ali Nem
  • 5,252
  • 1
  • 42
  • 41
  • 1
    The most important part of the original (v1) answer is that it actually cancels the request: ```Retrofit RxJava connector will redirect this call to okHttp's cancel. See here: ``` .. missing in this answer (the old link is broken now) – minsk Jan 30 '18 at 04:37
  • It is still true for Retrofit RxJava2 call adapter will forward disposable signal to okhttp `cancel`. I have updated the link. Just use regular rxjava cancel mechanism, no custom code is needed. – Sergii Pechenizkyi Mar 20 '19 at 09:34