O que há de novo no RxJava 3

Na primavera de 2020, foi lançada uma versão nova do framework RxJava , o RxJava 3. Vamos ver quais são as principais alterações, como você pode alternar do RxJava 2 para a nova versão e se vale a pena migrar.



Observe que não há alterações globais na nova versão, mas o suporte ao Java 8 apareceu e a biblioteca se tornou mais conveniente de usar.







Isenção de responsabilidade: este artigo é baseado em uma revisão do GitHub . Além disso, compartilhamos as impressões de nossos desenvolvedores de dispositivos móveis sobre o RxJava 3, mas não pretendemos ser um estudo exaustivo - porque a nova versão foi lançada recentemente e ainda não há muita experiência prática. Se você tiver alguma adição, escreva nos comentários, teremos o maior prazer em discutir)



Principais alterações no RxJava 3



Então, o que vemos no RxJava 3 :



  • A versão base do Java agora foi aumentada para 8 *;
  • Há suporte para recursos de idioma como:


- Fluxos

- Coletores de fluxo

- Opcional

- CompletableFeature



* Para usar a API Java8, é necessário elevar o minSDK para a versão 24.



Por sua vez, os desenvolvedores removeram o suporte para recursos como:



  • java.time.Duration - gera muitas sobrecargas, sempre pode ser substituído por time + unit;
  • java.util.function - Não é possível gerar exceções, e sobrecargas podem criar "ambiguidade" desnecessária.


A estrutura do pacote também foi alterada:







As alterações apresentadas podem ser divididas em 2 grupos:



  1. Mudanças comportamentais
  2. Mudanças na API


Mudanças comportamentais



  • Todos os erros serão processados


Anteriormente, um dos problemas com o RxJava 2 era que, em alguns casos, os erros podiam se perder e não serem tratados. Agora, no RxJava 3, a desinscrição de uma fonte que pode gerar um erro aciona esse erro para ser lançado no manipulador de erros geral via RxJavaPlugins.onError ()







  • Connectable.reset ()


Houve um problema de fontes termais no RxJava 2: ao receber um evento de terminal ConnectableObservable, novas conexões ignoravam todos os itens e apenas recebiam o evento de término.



O RxJava 3 apresenta uma função para redefinir o estado ConnectableObservable usando a função reset () para permitir que assinantes recém-conectados processem dados.











  • Capacidade de pausar Flowable.publish


No RxJava 3, após o recebimento de um determinado número de valores, o Flowable.publish é pausado e os elementos restantes ficam disponíveis para os assinantes subsequentes.







  • Parâmetro nulo Processor.offer ()


Se você tentar chamar PublishProcessor.offer (), BehaviourProcessor.offer () ou MulticastProcessor.offer () e passar nulo, uma NullPointerException será lançada em vez de passar um erro ao manipulador onError e um estado do terminal será acionado.







  • CompositeException.getCause ()


Anteriormente, no RxJava 2, o método getCause () às vezes era uma carga de memória significativa, chamando o método initCause em cada exceção, era instável e nem sempre lançava uma cadeia de exceções.



Na nova versão, esse método foi alterado por dentro e agora gera uma cadeia de erros na forma de um rastreamento de pilha - pela formatação simples de cadeias.











  • Exceções de validação de parâmetro alteradas


Se o parâmetro for inválido, agora alguns operadores lançam IllegalArgumentException em vez de IndexOutOfBoundsException:



- skip

- skipLast

- takeLast

- takeLastTimed



  • Fontes de pré-fechamento para fromX ()


As bibliotecas fromAction () e fromRunnable () tornaram-se consistentes com o restante das chamadas fromX (). Os retornos de chamada fromRunnable () e fromAction () agora serão fechados instantaneamente quando chamados em conformidade. No RxJava 2, esses operadores foram fechados após o final da execução do corpo do lambda passado para os parâmetros.







  • Ordem de limpeza de recursos ao usar using ()


A instrução using () possui um parâmetro responsável por quando o recurso usado será limpo (verdadeiro antes da conclusão, falso depois). Na versão inicial da biblioteca, esse parâmetro era ignorado e o recurso sempre era limpo antes de obter o estado do terminal, mas no RxJava 3 tudo funcionava corretamente.







Mudanças na API



  • O tratamento de exceção de interfaces funcionais da nova versão da biblioteca foi estendido de Exception para Throwable


  • Novos tipos: Fornecedor


No RxJava 3, em conexão com a extensão de exceções de interfaces funcionais de Exceção para Throwable, um novo tipo de Fornecedor foi introduzido - análogo ao Callable, mas com throws Throwable







  • No RxJava 3, os operadores para converter uma fonte de dados em outra foram alterados para conversores específicos










  • Componentes movidos


Devido ao fato de o RxJava3 oferecer suporte à API Java8, surgiu uma nova solução para substituir classes de fábrica individuais: os métodos dessas fábricas tornaram-se métodos estáticos da interface Disposable.



Como era antes:







agora:





  • Para reduzir os avisos, a classe DisposableContainer que foi usada dentro do CompositeDisposable faz parte da API pública
  • Alguns dos operadores do RxJava 2 estavam na fase experimental e, na terceira versão, tornaram-se operadores padrão:


Flowable promotions



dematerialize(Function)



Observable promotions

dematerialize(Function)



Maybe promotions



doOnTerminate(Action)

materialize()



Single promotions



dematerialize(Function)

materialize()



Complectable promotions



delaySubscription(long, TimeUnit)

delaySubscription(long, TimeUnit, Scheduler)

materialize()



  • concatMap() Scheduler’






  • blockingForEach()






  • blockingSubscribe() Maybe, Single Completable






  • onErrorComplete()
  • onErrorResumeWith() Completable
  • retryUntil() Single Completable






  • switchOnNext() switchOnNextDelayError() Maybe, Single Completable






  • dematerialize() Maybe






  • fromX()-






  • timeInterval() Maybe Single






  • toFuture() Maybe Completable
  • ofType() Maybe Single
  • doOnLifecycle() Maybe, Single Completable
  • concatMapX() (X – ) Maybe Single
  • concatDelayError() Maybe, Single Completable
  • mergeArray() Single






  • startWith()


Flowable

startWith(MaybeSource)

startWith(SingleSource)

startWith(ComplectableSource)



Observable

startWith(MaybeSource)

startWith(SingleSource)

startWith(ComplectableSource)



Maybe

startWith(Publisher)

startWith(ObservableSource)

startWith(MaybeSource)

startWith(SingleSource)

startWith(ComplectableSource)



Single

startWith(Publisher)

startWith(ObservableSource)

startWith(MaybeSource)

startWith(SingleSource)

startWith(ComplectableSource)



Complectable

startWith(MaybeSource)

startWith(SingleSource)



  • onErrorReturn() Completable






  • safeSubscribe() Maybe, Single Completable






  • flatMap() Single






  • concatEager() concatEagerDelayError() Flowable, Observable, Maybe Single
  • fromSupplier()










Java8





Adicionado novo operador deOptional () para Flowable, Observable e Maybe





Adicionado novo operador deStream () para Flowable e Observable









Adicionado novo operador deCompletionStage () para todos os cinco tipos de fonte de dados









Adicionado novo operador mapOptional () para Flowable, Observable, Maybe e Single. Ele apenas permite que valores não vazios passem.Adicionado







novo operador blockingStream () para Flowable e Observable. O operador representa o fluxo de dados como um fluxo, enquanto é recomendável fechá-lo após a conclusão do trabalho com ele, a fim de evitar todos os tipos de vazamentos.







Adicionado novos operadores flatMapStream () econcatMapStream () para Flowable e Observable - permite que cada item seja convertido em um fluxo separado.







Novos operadores adicionados flattenStreamAsFlowable () e flattenStreamAsObservable () para Maybe e Single - operadores flatMapStream () equivalentes para Observable e Flowable







O que é renomeado



  • Em vez de startWith () - startWithArray () , startWithIterable () , startWithItem ()
  • Em vez de onErrorResumeNext () - onErrorResumeWith ()
  • Em vez de zipIterable () - zip ()
  • Em vez de combineLatest () (com um argumento de matriz) - combineLatestArray () , combineLatestArrayDelayError ()
  • Em vez de Single.equals () - sequenceEqual (SingleSource, SingleSource)
  • Maybe.flatMapSingleElement() – Maybe.flatMapSingle()
  • Callable – Supplier ( )


API



Maybe.toSingle (), substituição - Maybe.defaultIfEmpty ()

subscrever (..., ..., ...,), substituição - doOnSubscribe ()

Single.toCompletable (), substituição - Single.ignoreElement ()

Completable.blockingGet (), substituição - Completable .blockingAwait ()

replay (Scheduler), replace - observeOn (Scheduler)

desmaterializa (), replace - desserialize (Function)

onExceptionResumeNext (), substitui - onErrorResumeNext (Function)

combineLatest () (com parâmetro vararg), substitui - combineLatestArray ()

fromFuture () (com parâmetro Scheduler), substituição - subscribeOn ()

concatMapIterable () (com parâmetro buffer), substituição - concatMapIterable (Function)



Também foram removidos os seguintes métodos do TestSubscriber e TestObserver:







Como migrar



Muitos desenvolvedores observam que a migração do RxJava 2 para o RxJava 3 é um processo bastante trabalhoso. Existem duas opções para fazer a transição:



  • tenha as duas versões da biblioteca em seu projeto;
  • faça uma migração completa para o RxJava 3, enquanto você pode usar uma biblioteca especial .


Então, como migrar:



  • Para atualizar o trabalho com a API - use análogos dos métodos RxJava 2 que foram sujeitos a alterações.
  • É importante levar em consideração que algumas bibliotecas de terceiros ainda estão "paradas" no RxJava 2. Para simplificar a transição, você pode usar o RxJavaBridge , que oculta a maior parte da migração oculta.
  • Retrofit RxJava3CallAdapterFactory .




Analisamos o que há de novo no RxJava 3. E agora vamos tentar responder à pergunta principal - vale a pena migrar?



O RxJava 3 é praticamente uma melhoria de API. Devido ao fato de não haver alterações fundamentais, em geral não há necessidade de migrar para a versão mais recente no momento. A transição em si exige esforço, embora muitas bibliotecas de terceiros ainda estejam associadas ao RxJava 2, para trabalhar com o Java8, você precisará adicionalmente elevar o minSDK para a versão 24. Algumas equipes também oferecem soluções alternativas, como o uso de Kotlin Coroutines.



No entanto, vale a pena notar que o RxJava 2 agora está entrando no modo de "manutenção", o que significa que haverá apenas correções de erros nas atualizações. O suporte para a segunda versão deve terminar em 28 de fevereiro de 2021.



! , .



All Articles