Netflix/RxJava — pull request #1203 by drbild (2014-05-15 07:34:51+00:00)
Title: AndroidObservable to hold weak reference to Activity or Fragment

bindActivity() and bindFragment() hold strong references to the
Activity or Fragment, thus requiring explicit unsubscription to avoid
leaks. This commit weakens that reference.

The observable chain should never be the owner of an Activity or
Fragment, so weakening the reference here should be safe. An earlier
version of bindActivity() used weak references for both the Activity
and the source Observable. Weakening the reference to the Observable may
be unsafe, as the observable chain might be the owner of an anonymous
source Observable.

This commit removes the need to explicitly unsubscribe, as long as the
final Subscriber holds only a weak reference to the Context (i.e.,
View, Activity, or Fragment).

For example, consider a class:
````
public class ClickableProperty extends Subscriber {

private final WeakReference mViewRef;

public ClickableProperty(View view) {
mViewRef = new WeakReference(view);
}

@Override
public void onNext(Boolean clickable) {
View view = mViewRef.get();
if (view != null) {
view.setClickable(clickable);
} else {
unsubscribe();
}
}

@Override
public void onCompleted() {
// ignore
}

@Override
public void onError(Throwable e) {
// ignore
}

}
````
The clickable property of a view can be safely bound to a boolean
observable as follows, without needing to explicitly unsubscribe in the
Activity's onDestroy().
````
public class MainActivity extends Activity {

Button mButton;

protected void onCreate(Bundle savedInstanceState) {
setContextView(R.id.activity_main);
mButton = findViewById(R.id.button);

Observable allowClicks = GlobalStaticObservables.allowClicks();
ClickableProperty clickableProperty = new ClickableProperty(mButton);
bindActivity(this, allowClicks).subscribe(clickableProperty);
}

protected void onDestroy() {
// nothing to do here
}

}
````
Without weakening the Activity reference in bindActivity(), explicit
unsubscription would still be needed to prevent Context leaks.