I did a little test setup to find out. This is not an Android application, but imitates class relationships. Here's what it looks like:
class Context class View(val context: Context) { lateinit var listener: () -> Unit fun onClick() = listener.invoke() } fun View.clicks() = Observable.fromEmitter<String>({ emitter -> listener = { emitter.onNext("Click") } }, Emitter.BackpressureMode.DROP) var ref: PhantomReference<Context>? = null fun main(args: Array<String>) { var c: Context? = Context() var view: View? = View(c!!) view!!.clicks().subscribe(::println) view.onClick() view = null val queue = ReferenceQueue<Context>() ref = PhantomReference(c, queue) c = null val t = thread { while (queue.remove(1000) == null) System.gc() } t.join() println("Collected") }
In this snippet, I create a View instance containing a reference to Context . the view has a callback for click events that I wrap in an Observable . I call the callback once, then I remove all references to View and Context and save the PhantomReference . Then, in a separate thread, I wait until the Context instance is released. As you can see, I never unsubscribe from Observable .
If you run the code, it will print
Click
Assembled
and then complete the verification that the Context reference has indeed been released.
What does this mean for you
As you can see, the Observable will not prevent the collection of objects referenced by the objects if the only links it has for it are circular. You can learn more about circular links in this question .
However, this is not always the case. Depending on the operators you use in the observed chain, the link may leak, for example. by the scheduler, or if you combine it with an infinite observable, such as interval() . Exclusively unsubscribing from an observable is always a good idea, and you can reduce the required template using something like RxLifecycle .
source share