Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: subscriber gets garbage collected prematurely #979

Closed
samueltardieu opened this issue Mar 22, 2014 · 6 comments
Closed

Android: subscriber gets garbage collected prematurely #979

samueltardieu opened this issue Mar 22, 2014 · 6 comments

Comments

@samueltardieu
Copy link
Contributor

The code in OperatorWeakBinding.java creates a weak reference onto the subscriber in addition to a weak reference onto the Android component.

Not keeping a strong reference on the subscriber is wrong. I have had a lot of non-delivered messages on cgeo, because we use code like:

   AndroidObservable.bindActivity(this, someObservable).subscribe(new Observer<…> {
      // Do something with the data, such as display it in a view
      …
   });

The only reference to the subscriber is in the subscription. If it is transformed into a weak reference, it will be garbage collected much too soon. This is a major departure from the usual (non-Android) RxJava subscription model.

I think the subscriber should be kept as-is and not be kept as a weak reference only.

I understand that this has been done so that the activity life cycle is not extended due to the subscriber keeping a reference onto it. I think this is the subscriber responsibility to keep only a weak reference to the activity (or fragment).

Maybe another mechanism to allow the subscriber to use a weak reference to the component should be found, but in the meantime, the current behaviour seems just wrong to me.

samueltardieu added a commit to cgeo/cgeo that referenced this issue Mar 22, 2014
There is an ongoing problem with RxJava, discussed at
ReactiveX/RxJava#979

This version includes a patch available at
https://github.com/cgeo/RxJava/commit/9ffb27f310d9f454d10d4d03206d8b5a262f6d63

fixup! Upgrade to RxJava 0.17.1
@samueltardieu
Copy link
Contributor Author

cc @mttkay

@mttkay
Copy link
Contributor

mttkay commented Mar 25, 2014

I see what you mean. The rationale behind using a weak reference to the subscriber is that in most of the cases, it'll be an inner class of the activity (in your case, too.) If we would hold a strong reference to the observer, we would hold a strong reference to the Activity too, so for the life time of the sequence your Activity would immediately leak when attempting to destroy it.

That said, it's not as simple as turning a weak reference into a strong reference, but I totally see your point. I'm open for suggestions here, as I've tried many approaches to solve these issues and we keep finding (edge) cases where the solutions collapse.

@samueltardieu
Copy link
Contributor Author

On the top of my head: couldn't we find a way to give the Android component back to the subscriber?

Something like

   def bindActivity[T <: Activity, U](activity: T, sourceObservable: Observable[U]): Observable[(T, U)]

This way, the subscriber will get a reference to the activity with every item and doesn't need to keep strong references to it.

Of course, it means that the user needs to be cautious in not closing over the activity through other references, but it can do so by declaring the subscriber in the companion object rather than in the activity itself if they are not sure to do it correctly.

@samueltardieu
Copy link
Contributor Author

(forget my remark about the companion object, I was thinking in Scala term, I meant "as a static method" in Java :-)

@benjchristensen
Copy link
Member

@samueltardieu Is this still an issue? I believe that as of #1021 that was merged this should no longer be happening.

@samueltardieu
Copy link
Contributor Author

Exactly. Closing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants