Saturday 29 January 2022

RxJava Single - Getting a memory leak, how to correctly unsubscribe?

I'm using RxJava's Single.fromCallable() to wrap around a third party library that makes an API call. I was testing different states on the call, success, failed, low network, no network.

But on the no network test I ran into a memory leak for the first time ever using RxJava. I spent the last hour combing through the code and trying to narrow down the leak with the LeakCanary library.

I figured out it was coming from subscribing to the Single.fromCallable().

Single.fromCallable(() -> {
       return remoteRepository.makeTransaction(signedTransaction).execute();
})
       .subscribeOn(Schedulers.newThread())
       .observeOn(AndroidSchedulers.mainThread())
       .subscribe(txHash -> {
              Log.d(TAG, "makeTransaction: " + txHash);
                    
                   
       }, err -> {
             Log.e(TAG, "makeTransaction: ", err);
                    
       });

Once I remove the

.subscribe(txHash -> { ... });

It no longer leaks.

I've tried googling stackoverflow with RxJava Single unsubscribe and I'm getting answers saying that you don't need to unsubscribe from Single

https://stackoverflow.com/a/43332198/11110509.

But if I don't I'll be getting memory leaks.

I've tried to unsubscribe by making the Single call an instance variable in my ViewModel:

Disposable mDisposable;

mDisposable = Single.fromCallable(() -> {...}).subscribe(txHash -> {..});

and unsubscribing it in the Fragment's onDestroy() method so it will unsubscribe if the user exits the screen before the call is finished.

@Override
    public void onDestroy() {
        super.onDestroy();
        mViewModel.getDisposable().dispose();
    }

But it's still leaking. I'm not sure if this is the correct way to unsubscribe or maybe I'm doing something else incorrectly.

How can I correctly unsubscribe from the Single Callable?



from RxJava Single - Getting a memory leak, how to correctly unsubscribe?

No comments:

Post a Comment