Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava, What happened if I don't call dispose?

My Android app needs to support to upload a big file, but I do not want a user wait until the upload is completed.

Usually, when I use Observable, I call dispose() for it when the view is destroyed.

But in uploading case, I can not dispose it in any case until it finished.

So I was thinking to try to like this,

private val compositeDisposable: CompositeDisposable = CompositeDisposable()

fun upload() {
    val disposable = Observable.just(true).delay(20, TimeUnit.SECONDS).subscribe({
        Log.d("=>", "Upload finished")
        disposeUploader()
    })  

    compositeDisposable.add(disposable)
}

fun disposeUploader() {
    compositeDisposable.clear()
    compositeDisposable.dispose()
}

But the problem is the upload() could be called multiple times, so the first uploader will dispose of all other processing calls.

What happened if I don't call dispose? or is there any way dispose of itself when it is completed?

like image 441
Expert wanna be Avatar asked Dec 07 '17 05:12

Expert wanna be


People also ask

What is dispose in RxJava?

The Disposable is a link between an Observable and an active Observer, and you can call its dispose() method to stop emissions and dispose of all resources used for that Observer.

What is disposable reactive programming?

A Disposable is a stream or a link between an Observable and an Observer . A quick check of the documentation shows that it has two main methods, dispose() and isDisposed() . The former disposes of the link, while the latter checks if the link has been disposed.

How do you dispose of observables?

It is good practice to dispose complete observable chain running in your Activity or Fragment Life-Cycle. A typical example of disposing an Observable: In above example, you can see that in doTask() method, disposable is added to CompositeDisposable and in onStop observable is disposed using compositeDisposable.

Is RxJava deprecated?

RxJava, once the hottest framework in Android development, is dying. It's dying quietly, without drawing much attention to itself.


1 Answers

The idea of disposing an Observable serves two purposes:

1) Avoid memory leaks - detach view references that might be held by ongoing request module.
2) Release resources - stop ongoing background task to free unneeded resources, when the user exit your activity for instance, a request/processing might not be relevant anymore, so no point to keep it running.

In your case you want your background task (uploading file) to resume, avoiding (2), while having your view detaching from it (1).

Your solution of disposing after some period of time miss the point as Observable will dispose itself at completion. moreover, you can't assume a specific duration for the upload (at most it is timeout value).

The solution with RxJava is multicasting your Observable using operator like publish and share, in your case:

val multicastedObservable = uploadObservable.publish()
            .autoConnect()
            .subscriber(//your view related subscriber);

This way, uploadObservable will start execute at first subscribe but will not stop when dispose is called, but rather will detach the reference to view.


Having said all that, it's worth noting that your upload scenario cannot be done reliably without foreground service in Android.

like image 135
yosriz Avatar answered Sep 20 '22 00:09

yosriz