La enseñanza más fácil de entender para usar RxJava3 (2)

Terminología en Rxjava

1. Aguas arriba y aguas abajo

El flujo de datos en RxJava incluye una fuente de datos, 0 o más pasos intermedios, un consumidor de datos o subpasos combinados (los pasos son responsables de usar el flujo de datos de cierta manera):

source
  .operator1()
  .operator2()
  .operator3()
  .subscribe(consumer)

Desde la perspectiva del operador2, la fuente de la izquierda está aguas arriba y la suscripción (consumidor) de la derecha está aguas abajo.

2. El objeto del movimiento

En la documentación de RxJava, emisión, emisiones, elemento, evento, señal, datos y mensaje son sinónimos, y todos significan objetos que se mueven a lo largo del flujo de datos.

3. Contrapresión

El uso de contrapresión permite que el paso actual limite el uso de la memoria del flujo de datos cuando generalmente es imposible saber cuántos elementos de datos se enviarán en sentido ascendente.
En RxJava, las Flowableclases están diseñadas para soportar la contrapresión y las Observableclases están dedicadas a operaciones sin contrapresión. Single, Maybe y Completable tampoco soportan la contrapresión.

4. Programadores

Los operadores de RxJava no usan directamente Thread o ExecutorServices, pero usan el llamado Programador, que abstrae la fuente de concurrencia detrás de la API unificada.
Tipo de uso del programador

  1. Schedulers.computation (): Ejecuta trabajo computacionalmente intensivo en un número fijo de subprocesos dedicados en segundo plano. La mayoría de los operadores asincrónicos utilizan esto como su planificador predeterminado.
  2. Schedulers.io (): Ejecute operaciones de bloqueo o E / S similares en un grupo de subprocesos que cambian dinámicamente.
  3. Schedulers.single (): Ejecuta el trabajo en un solo hilo de forma secuencial y FIFO.
  4. Schedulers.trampoline (): Ejecuta trabajos de forma secuencial y FIFO en los hilos participantes, generalmente con fines de prueba.
    Por supuesto, ciertas plataformas también tienen otro uso de programación , como el sistema Android tiene un uso adicional:
    AndroidSchedulers.mainThread(), SwingScheduler.instance() or JavaFXSchedulers.gui().

También puede utilizar un servicio de programación de tareas ExecutorService [^ 1] personalizado a través del método Scheduler .from (Executor) . Tendrá un grupo de subprocesos más grande pero aún fijo (diferente de usar compute () e io () por separado).

Uso de observador y observable en Rxjava

El escenario de aplicación principal de la biblioteca de programación receptiva RxJava es asincrónico. Observer y Observable en
RxJava son dos clases o interfaces importantes. A continuación realizamos una prueba sencilla.

(1) Primero cree una instancia de Observable.

  1. Hay muchos métodos de creación, como create (), defer (), just (), from (), rang (), timer (), interval (), etc. Aquí se utiliza la creación más utilizada, y su parámetro es una instancia de ObservableOnSubscribe .
  2. ObservableOnSubscribe # subscribe ( emisor ObservableEmitter ) se volverá a llamar en este momento . El subscribe (emisor ObservableEmitter) hará una devolución de llamada de respuesta cuando el Observable esté suscrito, y su respuesta es después del método Observer # onSubscribe (Disposable d).
    private ObservableEmitter<String> mEmitter;
    private Observable<String> mObservable;

    private void createObservable() {
    
    
        mObservable = Observable.create(new ObservableOnSubscribe<String>() {
    
    
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
    
    
                Log.i(TAG, "  Observable  has  create");
                mEmitter = emitter;
            }
        });
    }

Llamar al método createObservable () subscribe (emisor ObservableEmitter) no responderá.

(2)
Para obtener una explicación detallada de los cuatro métodos de instanciar un objeto Observer Observer, consulte Observer

    private Observer<String> mObserver = new Observer<String>() {
    
    
        @Override
        public void onSubscribe(Disposable d) {
    
    
            Log.i(TAG, "  +++ onSubscribe");
            if (d != null) {
    
    
                System.out.println("  d.hashCode()=" + d.hashCode() + "  mEmitter.hashCode() " + mEmitter.hashCode());
                System.out.println("  d.getClass()=" + d.getClass().getCanonicalName());
            }
        }

        @Override
        public void onNext(String s) {
    
    
            Log.i(TAG, "  +++ onNext" + s);
        }

        @Override
        public void onError(Throwable e) {
    
    
            Log.i(TAG, "  +++ onError");
        }

        @Override
        public void onComplete() {
    
    
            Log.i(TAG, "  +++ onComplete");
        }
    };

(3) Observable se suscribe a
mObservable.subscribe (mObserver);
debe tenerse en cuenta que suscríbase para suscribirse (mObserver) varias veces, encontrará

        public void onSubscribe(Disposable d) {
    
    
            Log.i(TAG, "  +++ onSubscribe");
            if (d != null) {
    
    
                System.out.println("  d.hashCode()=" + d.hashCode() + "  mEmitter.hashCode() " + mEmitter.hashCode());
                System.out.println("  d.getClass()=" + d.getClass().getCanonicalName());
            }
        }
  1. El método observer.onSubscribe se llama antes que Observable.subscribe

I: +++ onSubscribe
I: d.hashCode () = 464508421
I: d.getClass () = io.reactivex.internal.operators.observable.ObservableCreate.CreateEmitter
I: Observable has create

  1. d.getClass () = io.reactivex.internal.operators.observable.ObservableCreate.CreateEmitter sabe que d en onSubscribe (Disposable d) es una clase Emitter
  2. Al llamar a mObservable.subscribe (mObserver) varias veces, verifique el resultado de la impresión de la siguiente manera:

I / System.out: d.hashCode () = 464508421
I / System.out: mEmitter.hashCode () 464508421
I / System.out: d.hashCode () = 703714906
I / System.out: mEmitter.hashCode () 703714906
I / System.out: d.hashCode () = 786686091
I / System.out: mEmitter.hashCode () 786686091

Cada vez que se llama a mObservable.subscribe (mObserver), habrá una nueva subclase de implementación de Emitter y Disposable ( Disposable d y ObservableEmitter emitter hashCode son exactamente iguales ).
Explique que Observable.subscribe () creará un nuevo ObservableEmitter cada vez .

(4)
Después de que el observable cambia el estado del Observable, el ObservableEmitter transmite los datos a través de los métodos onNext, onComplete y onError, y el Observador suscrito responderá a los métodos onNext, onComplete y onError correspondientes. Como método de ejecución:

 mEmitter.onNext("Hello");
 mEmitter.onComplete();

La secuencia de respuesta del método es

ObservableEmitter.onNext
Observer.onNext
ObservableEmitter.onComplete
Observer.onComplete
y encontró que mEmitter.hashCode no cambiará

Si realiza varias mEmitter.onNext("Hello"); mEmitter.onComplete();operaciones,
solo hay ObservableEmitter.onNext 、 ObservableEmitter.onCompletedos formas de responder.
Observer.onNext 、 Observer.onCompleteNo responderé. Esto está verificado. El observador solo responderá una vez al mismo cambio de estado.

Los enlaces relacionados son los siguientes:

Supongo que te gusta

Origin blog.csdn.net/luo_boke/article/details/105579864
Recomendado
Clasificación