Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing RxBindings Observable events between multiple subscribers

I'm using a Focus Observable from the RxBindings library to react on focus changes. As I want to either validate input and trigger an animation I need the focus events twice. Jake Wharton recommends to use the share() operator for multiple subscriptions on one observable. But if I manipulate the observable after using share() the first subscription is dead.

This is a small example of my usecase

public class ShareTest extends AppCompatActivity {

@Bind(R.id.editTextOne)
EditText editTextOne;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_share_test);

    ButterKnife.bind(this);

    Observable<Boolean> focusChangeObservable = RxView.focusChanges(editTextOne);
    focusChangeObservable.subscribe(focused -> Log.d("test","Subscriber One: "+focused));

    focusChangeObservable.share().skip(1).filter(focused -> focused == false).subscribe(focused -> {
        Log.d("test","Subscriber Two: "+focused);
    });
}
}

What I need and expected was an output when I gain and loose the focus on the EditText is

Focus gain
Subscriber One: true

Focus loss
Subscriber One: false
Subscriber Two: false

But what I actually get is

Focus gain

Focus loss
Subscriber Two: false

So it seems the manipulation of the second case overrides the first one. What am I doing wrong and what is the intended way to share events between multiple subscribers when they are manipulated differently

Thanks

like image 647
user1033552 Avatar asked Jan 25 '16 07:01

user1033552


1 Answers

RxView.focusChanges() Observable sets new OnFocusChangeListener on View each time you subscribe to it, so the previous listener will not get any new calls.

In your code you have two subscriptions - first directly on focusChangeObservable and the second one is share operator

Turning your observable into a ConnectableObservable via share operator is a good idea, though you need to subscribe to Observable returned by share each time f.e :

    final Observable<Boolean> sharedFocusChangeObservable = focusChangeObservable.share();
    sharedFocusChangeObservable.subscribe(focused -> Log.d("test","Subscriber One: "+focused));
    sharedFocusChangeObservable.skip(1).filter(focused -> focused == false).subscribe(focused -> {
        Log.d("test","Subscriber Two: "+focused);
    });
like image 166
krp Avatar answered Oct 30 '22 12:10

krp