Skip to content

Instantly share code, notes, and snippets.

@oldergod
Last active July 25, 2023 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oldergod/742ac0de0cc699fe1d0361bdae29a5d2 to your computer and use it in GitHub Desktop.
Save oldergod/742ac0de0cc699fe1d0361bdae29a5d2 to your computer and use it in GitHub Desktop.
Managing RxState Ending point
/**
* Many things are omitted to focus on the relevant data.
*/
public class Activity extends AppCompatActivity {
Binder binder;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
Object lastCustomNonConfigInstance = getLastCustomNonConfigurationInstance();
if (lastCustomNonConfigInstance != null) {
binder = (Binder) lastCustomNonConfigInstance;
} else {
binder = new Binder();
}
bind();
}
private void bind() {
binder.getStatesAsObservable().subscribe(this::render);
binder.forwardIntents(intents());
}
public Observable<Intent> intents() {
return Observable.merge(loadFirstPageIntent(), loadNextPageIntent());
}
@Override public Object onRetainCustomNonConfigurationInstance() {
return binder;
}
}
/**
* Many things are omitted to focus on the relevant data.
* See Jake's talk for the flow explanation: http://jakewharton.com/the-state-of-managing-state-with-rxjava/
*/
class Binder {
private PublishSubject<Intent> intentsSubject = PublishSubject.create();
private PublishSubject<ViewState> statesSubject = PublishSubject.create();
Binder() {
compose().subscribe(state -> statesSubject.onNext(state));
}
private Observable<ViewState> compose() {
return intentSubject
.scan(intentReducer)
.map(this::actionFromIntent)
.compose(actionToResultTransformer)
.scan(ViewState.idle(), reducer);
}
public void forwardIntents(Observable<Intent> intents) {
intents.subscribe(intent -> IntentSubject.onNext(intent));
}
public PublishSubject<ViewState> getStatesAsObservable() {
return statesSubject;
}
private BiFunction<Intent, Intent, Intent> intentReducer =
(previousIntent, newIntent) -> {
// i.e. we are inside the scan, meaning there has already
// been intent in the past, meaning the InitialIntent cannot
// be the first => it is a config change.
if (newIntent instanceof Intent.InitialIntent) {
return Intent.GetLastState.create();
} else {
return newIntent;
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment