OnNext comience otro Observable
¿Hay alguna manera más limpia de hacer lo siguiente?
Tengo un observable de Android que debuta las peticiones. OnNext llama a una segunda observable.
- RxJava y eventos esporádicos al azar en Android
- Observable vs Flujo rxJava2
- Rx java retrofit 2 manejo de errores
- Observable.just () que devuelve Unidad en Kotlin
- ¿Cómo puedo interceptar un objeto observable y modificarlo en RxJava antes de volver al suscriptor?
{// when creating the android activity searchTextEmitterSubject = PublishSubject.create(); subscription = AndroidObservable.bindActivity(this, Observable.switchOnNext(searchTextEmitterSubject)) .debounce(100, TimeUnit.MILLISECONDS, Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(String s) { Log.d("a",s); pa.doSearch(s); } }); } @OnTextChanged(R.id.ed) public void onTextEntered(CharSequence charsEntered) { searchTextEmitterSubject.onNext(getASearchObservableFor(charsEntered.toString())); } private Observable<String> getASearchObservableFor(final String searchText) { return Observable.create( (Subscriber<? super String> subscriber) -> subscriber.onNext(searchText)).subscribeOn(Schedulers.io()); }
DoSearch instancia una segunda observable:
public void doSearch(String string) { AlbumEndpoint albumEndpoint = API.getRestAdapter().create(AlbumEndpoint.class); Observable<Point> observable = albumEndpoint.searchPoint(string); mAdapterDataSubscription = AndroidObservable.bindActivity((Activity) getContext(), observable) .subscribe(mAdapterDataObserver); } private Observer<Point> mAdapterDataObserver = new Observer<Point>() { @Override public void onCompleted() { mAdapterDataSubscription.unsubscribe(); } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(Point point) { List<Point.Result> results = point.getResults(); mData.addAll(results); notifyDataSetChanged(); } };
Funciona. ¿Pero hay una manera de "combinar" las dos corrientes en uno mejorando la legibilidad o para crear un código óptimo?
Editar : Por razones de integridad y cualquier persona interesada en el futuro me las arreglo para encoger el código en:
Observable<EditText> searchTextObservable = ViewObservable.text(ed); searchTextObservable.debounce(100, TimeUnit.MILLISECONDS) .flatMap(editText -> { String string = editText.getText().toString(); AlbumEndpoint albumEndpoint = getRestAdapter().create(AlbumEndpoint.class); return albumEndpoint.searchPoint(string); }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(mAdapterDataObserver);
- RxJava Observable.cache invalidate
- Utilizando RxJava para buscar objetos, transforma una lista contenedora y usa la lista
- Acceso al dominio desde un subproceso incorrecto Excepción mientras se envió una copia usando copyFromRealm
- RxAndroid, bus de eventos y ciclo de vida de la actividad
- Por qué definir Flowable podría recibir actualizaciones de la base de datos
- IdlingResource Espresso con RxJava
- Rx 2 Android ¿qué es mejor Single o Observable para llamadas api?
- Retrofit 2 + Rxjava error de manipulación
Un par de cosas:
No estoy seguro, ¿por qué está envolviendo los eventos de cambio de texto en un nuevo Observable cada vez en lugar de simplemente entregarlos a su tema de inmediato:
Por lo tanto, en lugar de:
@OnTextChanged(R.id.ed) public void onTextEntered(CharSequence charsEntered) { searchTextEmitterSubject.onNext(getASearchObservableFor(charsEntered.toString())); }
prueba esto:
@OnTextChanged(R.id.ed) public void onTextEntered(CharSequence charsEntered) { searchTextSubject.onNext(charsEntered.toString()); }
Por supuesto, entonces tendría un PublishSubject<String>
lugar de PublishSubject<Observable<String>>
.
Pero usted podría saltar el onNextSwitch
y apenas debounce
su asunto y continuar de allí.
Para simplificar aún más las cosas, sólo puede utilizar ViewObservables desde el paquete rxjava Android. No los he usado últimamente, pero debería funcionar así:
Observable<OnTextChangeEvent> searchTextObservable = ViewObservable.text(tvSearch);
A OnTextChangeEvent
se emitirá cada vez que se llama a AfterTextChanged de afterTextChanged
subyacente (en ButterKnife, por defecto, se utiliza onTextChanged
, por lo que puede ser una diferencia sutil).
En caso de que me faltó alguna razón importante para envolver cada cambio de texto en un Observable, esto también se puede lograr de una manera más sencilla:
@OnTextChanged(R.id.ed) public void onTextEntered(CharSequence charsEntered) { searchTextEmitterSubject.onNext( Observable.just(charsEntered.toString()) ); }
Tenga en cuenta que también omitió el subscribeOn(Schedulers.io())
– Nunca he sentido la necesidad de mover a los oyentes de eventos desde el hilo de interfaz de usuario a algún otro hilo. ¿Me estoy perdiendo de algo?
Finalmente, podrías usar flatMap
para ejecutar la búsqueda de cada término de búsqueda (estoy usando mi propio Observable<OnTextChangeEvent>
aquí):
searchTextObservable .debounce(100, TimeUnit.MILLISECONDS) .flatMap(new Func1<OnTextChangeEvent, Observable<Point>>() { @Override public Observable<Point> call(OnTextChangeEvent event) { final String string = event.text.toString(); AlbumEndpoint albumEndpoint = API.getRestAdapter().create(AlbumEndpoint.class); Observable<Point> pointObservable = albumEndpoint.searchPoint(string); return AndroidObservable.bindActivity((Activity) getContext(), pointObservable); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(mAdapterDataObserver);
Puede que necesite mover su pointObservable al subproceso de IO si el punto de entrada de álbum no lo hace ya.
¡Espero que esto ayude!
EDIT: Lo siento, me olvidé de explicar lo que es OnTextChangeEvent
. Eso es una parte de rx-android – puede echar un vistazo al código fuente aquí:
Es sólo un POJO simple que contiene una referencia al EditText que fue cambiado, así como el contenido actual del EditText. Este último es lo que estaba usando en el flatMap
.
- Crash al devolver el fragmento como una pestaña. Ver con la misma ID
- Cómo cambiar el color de fondo de un TextView dentro de un ActionMode