There is how I use RxBinding with Kotlin:
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
reset_password_text_view.clicks().subscribe { presenter.showConfirmSecretQuestionBeforeResetPassword() }
password_edit_text.textChanges().skip(1).subscribe { presenter.onPasswordChanged(it.toString()) }
password_edit_text.editorActionEvents().subscribe { presenter.done(password_edit_text.text.toString()) }
}
Observable.subscribe(action)
returns Subscription
. Should I keep it as reference and unsubscribe onPause()
or onDestroy()
?
Like this:
private lateinit var resetPasswordClicksSubs: Subscription
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
resetPasswordClicksSubs = reset_password_text_view.clicks().subscribe { presenter.showConfirmSecretQuestionBeforeResetPassword() }
}
override fun onDestroy() {
super.onDestroy()
resetPasswordClicksSubs.unsubscribe()
}
I've made a small test setup to find it out. It's not an Android app but it simulates the class relationships. Here's what it looks like:
In this snippet I instantiate a
View
that holds a reference to aContext
. the view has a callback for click events that I wrap in anObservable
. I trigger the callback once, then I null out all references to theView
and theContext
and only keep aPhantomReference
. Then, on a separate thread I wait until theContext
instance is released. As you can see, I'm never unsubscribing from theObservable
.If you run the code, it will print
and then terminate proving that the reference to the
Context
was indeed released.What this means for you
As you can see, an
Observable
will not prevent referenced objects from being collected if the only references it has to it are circular. You can read more about circular references in this question.However this isn't always the case. Depending on the operators that you use in the observable chain, the reference can get leaked, e.g. by a scheduler or if you merge it with an infinite observable, like
interval()
. Explictly unsubscribing from an observable is always a good idea and you can reduce the necessary boilerplate by using something like RxLifecycle.I think that Jake Wharton (the creator of the library) gave the best answer:
Yes, you should unsubscribe when using RxBinding.
Here's one way... (in java, could be tweaked for kotlin?)
Collect
Within your Activity or Fragment, add disposables to a CompositeDisposable that you'll dispose at onDestroy().
Dispose
Yep, if you look in the doc, it explicitely says: