-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
OperatorWeakBinding (deprecates OperatorObserveFromAndroidComponent) #938
OperatorWeakBinding (deprecates OperatorObserveFromAndroidComponent) #938
Conversation
|
||
private void handleLostBinding(Subscriber<? super T> sub, String context) { | ||
if (sub == null) { | ||
Log.d(LOG_TAG, "subscriber gone; skipping " + context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should guard this log call
RxJava-pull-requests #877 FAILURE |
private final WeakReference<Subscriber<? super T>> subscriberRef; | ||
private final WeakReference<R> boundRef; | ||
|
||
private WeakSubscriber(Subscriber<? super T> op, WeakReference<R> boundRef) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be super(op)?
@@ -95,4 +101,21 @@ private AndroidObservable() {} | |||
throw new IllegalArgumentException("Target fragment is neither a native nor support library Fragment"); | |||
} | |||
} | |||
|
|||
public static <T> Observable<T> bindActivity(Activity activity, Observable<T> cachedSequence) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't actually have to assume that the sequence is cached. A PublishSubject
doesn't cache but still makes sense to weakly bind to when not calling unsubscribe explicitly
Couldn't you, in addition, check |
That should not be necessary, and it is something that we only realized Android guarantees that it will not process messages entering the main So as long as you use OperatorWeakBinding with the main thread scheduler, bindActivity in AndroidObservable combines the two to achieve this. Does that make sense? |
I am more concerned about what happens when the activity is gone (replaced by another one) but not yet reclaimed by the GC. Won't items be delivered to the UI thread which is now unrelated to the previous activity? |
No that's what I tried to say: Android stops processing the main looper |
We obviously don't understand each other :) I'll try again. I'm not talking about the case where the activity is recreated, but where it is destroyed and another unrelated activity is started. The same thread can be reused for the UI of the new activity, and AFAIK (but I may be wrong) the looper is tied to a thread, not to the activity. I understand that the looper will be suspended between the previous activity death and the new activity creation, but won't queued messages then be delivered to the new activity which would use the same looper as the previous one? I have had cases where messages were delivered through a Handler to a destroyed activity, which manifested through an error while attempting to do UI operations on now-not-displayed components, and I wonder whether this could be the case here. |
Not if you unsubscribe from the Activity/subscriber in onDestroy or let the
|
The weak binding will unsubscribe when the activity is freed by the garbage collector. This may happen a long time after the activity is destroyed. This is not a synchronous process as it would be in Python where references are reference-counted. Here, we have to wait until the garbage collector decides to collect unreferenced objects for the weak reference to become null. (of course, when unsubscribing explicitly, there is no problem :-) |
FWIW, I should add that the implementation you're now using does not check Moreover, if we find we do need this check after all, I suggest we follow |
@samueltardieu Sorry for the delay, finally got time to work on this. You were right, there is a case in which this can still happen, which is when exiting the activity via the back button. I still couldn't reproduce it when going through a rotation change, but that case is sufficient to warrant a change or extension to this. My suggestion is then to extend this operator to also address what @tehmou asked for, which is to be able to pass in a predicate that tests for validity of the bound component. This could be
this test can then be customized, but the Does that make sense? I'll implement this, run some tests and then push it for you guys to reviews. |
RxJava-pull-requests #898 FAILURE |
RxJava-pull-requests #899 SUCCESS |
final WeakReference<Subscriber<? super T>> subscriberRef; | ||
|
||
private WeakSubscriber(Subscriber<? super T> source) { | ||
subscriberRef = new WeakReference<Subscriber<? super T>>(source); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to add super(source);
here to chain the Subscription
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
RxJava-pull-requests #900 SUCCESS |
RxJava-pull-requests #901 SUCCESS |
OperatorWeakBinding (deprecates OperatorObserveFromAndroidComponent)
Android UI operator that weakly binds to a fragment or activity. (see discussion in #899)