Rxjava는 반응성 확장의 Java VM 구현입니다. 관찰 가능한 서열을 사용하여 비동기 및 이벤트 기반 프로그램을 구성하기위한 라이브러리입니다.
옵저버 패턴을 확장하여 데이터/이벤트 시퀀스를 지원하고 선언적으로 시퀀스를 함께 구성 할 수있는 연산자를 추가하면서 저수준 스레딩, 동기화, 스레드 안전성 및 동시 데이터 구조와 같은 문제에 대한 우려를 추상화 할 수 있습니다.
Wiki Home에서 일반적으로 Rxjava에 대해 자세히 알아보십시오.
2.x에서 업그레이드 할 때 변경 및 마이그레이션 정보에 대한 자세한 내용은 3.0의 다른 내용을 읽으십시오.
2.X 버전은 2021 년 2 월 28 일 현재 수명이 끝납니다. 더 이상 개발, 지원, 유지 보수, PR 및 업데이트가 발생하지 않습니다. 마지막 버전 인 2.2.21 의 Javadoc은 계속 액세스 할 수 있습니다.
1.X 버전은 2018 년 3 월 31 일 현재 수명이 끝납니다. 더 이상 개발, 지원, 유지 보수, PR 및 업데이트가 발생하지 않습니다. 마지막 버전 인 1.3.8 의 Javadoc은 계속 액세스 할 수 있습니다.
첫 번째 단계는 예를 들어 Gradle 컴파일 종속성으로 Rxjava 3을 프로젝트에 포함시키는 것입니다.
implementation " io.reactivex.rxjava3:rxjava:3.x.y "
( x
와 y
최신 버전 번호로 바꾸십시오 :)
두 번째는 Hello World 프로그램을 작성하는 것입니다.
package rxjava . examples ;
import io . reactivex . rxjava3 . core .*;
public class HelloWorld {
public static void main ( String [] args ) {
Flowable . just ( "Hello world" ). subscribe ( System . out :: println );
}
}
Rxjava 3 구성 요소는 이제 io.reactivex.rxjava3
에 따라 거주하고 기본 클래스와 인터페이스는 io.reactivex.rxjava3.core
아래에 있습니다.
Rxjava 3은 연산자를 발견 할 수있는 여러 기본 클래스를 특징으로합니다.
io.reactivex.rxjava3.core.Flowable
: 0..n 흐름, 반응성 스트림 및 배압을 지원합니다io.reactivex.rxjava3.core.Observable
: 0..N 흐름, 배압 없음,io.reactivex.rxjava3.core.Single
: 정확히 1 항목 또는 오류의 흐름,io.reactivex.rxjava3.core.Completable
: 항목이없는 흐름이지만 완료 또는 오류 신호 만io.reactivex.rxjava3.core.Maybe
: 항목이없는 흐름, 정확히 하나의 항목 또는 오류.rxjava의 데이터 플로우는 소스, 0 이상의 중간 단계와 데이터 소비자 또는 콤비네이터 단계로 구성됩니다 (여기서 단계가 데이터 플로우를 방법으로 소비하는 데 도움이됩니다).
source . operator1 (). operator2 (). operator3 (). subscribe ( consumer );
source . flatMap ( value -> source . operator1 (). operator2 (). operator3 ());
여기서, 우리가 operator2
에 자신을 상상한다면, 소스쪽으로 왼쪽을 바라 보는 것을 상류 라고합니다. 가입자/소비자를 향한 오른쪽을 바라 보는 것을 다운 스트림 이라고합니다. 이것은 종종 각 요소가 별도의 줄에 기록 될 때 더 분명합니다.
source
. operator1 ()
. operator2 ()
. operator3 ()
. subscribe ( consumer )
Rxjava의 문서, 방출 , 방출 , 항목 , 이벤트 , 신호 , 데이터 및 메시지 는 동의어로 간주되며 데이터 흐름을 따라 이동하는 객체를 나타냅니다.
데이터 흐름이 비동기 단계를 통과하면 각 단계마다 다른 속도로 다른 것을 수행 할 수 있습니다. 임시 버퍼링 또는 데이터 건너 뛰기/삭제가 필요하기 때문에 일반적으로 메모리 사용량이 증가하는 것으로 나타나는 이러한 단계를 압도하지 않으려면 소위 배압이 적용되며, 이는 단계가 얼마나 품목 수를 표현할 수있는 유량 제어 형식 인 것입니다. 그들은 처리 할 준비가 되었습니까? 이를 통해 일반적으로 상류가 보낼 항목 수를 알 수있는 방법이없는 상황에서 데이터 플로우의 메모리 사용을 제한 할 수 있습니다.
Rxjava에서 전용 Flowable
클래스는 배압을 지원하도록 지정되며 Observable
비 백색 압력 작업 (짧은 서열, GUI 상호 작용 등)에 전념합니다. 다른 유형, Single
, Maybe
Completable
다른 유형은 배압도 지원하지 않아야합니다. 항상 일시적으로 하나의 품목을 저장할 공간이 있습니다.
다양한 중간 연산자를 적용하여 데이터 흐름의 준비는 소위 어셈블리 시간 에 발생합니다.
Flowable < Integer > flow = Flowable . range ( 1 , 5 )
. map ( v -> v * v )
. filter ( v -> v % 3 == 0 )
;
이 시점에서 데이터는 아직 흐르지 않으며 부작용이 발생하지 않습니다.
이것은 내부적으로 처리 단계를 설정하는 흐름을 subscribe()
할 때 임시 상태입니다.
flow . subscribe ( System . out :: println )
구독 부작용 이 트리거 된시기입니다 ( doOnSubscribe
참조). 일부 소스는이 상태에서 즉시 항목을 방출하기 시작합니다.
이것은 흐름이 적극적으로 항목, 오류 또는 완료 신호를 방출하는 상태입니다.
Observable . create ( emitter -> {
while (! emitter . isDisposed ()) {
long time = System . currentTimeMillis ();
emitter . onNext ( time );
if ( time % 2 != 0 ) {
emitter . onError ( new IllegalStateException ( "Odd millisecond!" ));
break ;
}
}
})
. subscribe ( System . out :: println , Throwable :: printStackTrace );
실제로, 이것은 위의 주어진 예의 본문이 실행될 때입니다.
rxjava의 일반적인 사용 사례 중 하나는 배경 스레드에서 일부 계산, 네트워크 요청을 실행하고 UI 스레드에 결과 (또는 오류)를 표시하는 것입니다.
import io . reactivex . rxjava3 . schedulers . Schedulers ;
Flowable . fromCallable (() -> {
Thread . sleep ( 1000 ); // imitate expensive computation
return "Done" ;
})
. subscribeOn ( Schedulers . io ())
. observeOn ( Schedulers . single ())
. subscribe ( System . out :: println , Throwable :: printStackTrace );
Thread . sleep ( 2000 ); // <--- wait for the flow to finish
이 스타일의 사슬 방법을 빌더 패턴과 유사한 유창한 API 라고합니다. 그러나 Rxjava의 반응성 유형은 불변입니다. 각 메소드 호출은 추가 된 동작으로 새로운 Flowable
반환합니다. 예를 들어, 예제는 다음과 같이 다시 작성할 수 있습니다.
Flowable < String > source = Flowable . fromCallable (() -> {
Thread . sleep ( 1000 ); // imitate expensive computation
return "Done" ;
});
Flowable < String > runBackground = source . subscribeOn ( Schedulers . io ());
Flowable < String > showForeground = runBackground . observeOn ( Schedulers . single ());
showForeground . subscribe ( System . out :: println , Throwable :: printStackTrace );
Thread . sleep ( 2000 );
일반적으로 계산을 이동하거나 IO를 subscribeOn
통해 다른 스레드로 차단할 수 있습니다. 데이터가 준비되면 observeOn
통해 전경 또는 GUI 스레드에서 처리 될 수 있습니다.
Rxjava 연산자는 Thread
S 또는 ExecutorService
S에서 직접 작동하지 않지만 소위 Scheduler
S에서 작동하지 않습니다. RXJAVA 3에는 Schedulers
유틸리티 클래스를 통해 액세스 할 수있는 여러 표준 스케줄러가 있습니다.
Schedulers.computation()
: 백그라운드에서 고정 된 수의 전용 스레드에서 계산 집중 작업을 실행합니다. 대부분의 비동기 연산자는 이것을 기본 Scheduler
로 사용합니다.Schedulers.io()
: 동적으로 변화하는 스레드 세트에서 I/O와 같은 또는 차단 작업을 실행합니다.Schedulers.single()
: 순차적이고 FIFO 방식으로 단일 스레드에서 작업을 실행하십시오.Schedulers.trampoline()
: 일반적으로 테스트 목적으로 참여 스레드 중 하나에서 순차적이고 FIFO 방식으로 작업을 실행합니다. 이들은 모든 JVM 플랫폼에서 사용할 SwingScheduler.instance()
있지만 Android와 같은 일부 특정 플랫폼 AndroidSchedulers.mainThread()
고유 한 일반 Scheduler
JavaFXScheduler.platform()
정의되어 있습니다.
또한 Schedulers.from(Executor)
통해 기존의 Executor
(및 ExecutorService
와 같은 하위 유형)를 Scheduler
로 래핑 할 수있는 옵션이 있습니다. 예를 들어, 더 크지 만 여전히 고정 된 스레드 풀 ( computation()
및 io()
와 달리)를 갖는 데 사용할 수 있습니다.
The Thread.sleep(2000);
결국에는 우연이 아닙니다. rxjava에서는 기본 Scheduler
가 데몬 스레드에서 실행됩니다. 즉, Java 메인 스레드가 종료되면 모두 중지되고 백그라운드 계산이 결코 일어나지 않을 수 있습니다. 이 예에서 얼마 동안 자고있는 상황에서는 여분의 시간이 지남에 따라 콘솔의 흐름 출력을 볼 수 있습니다.
rxjava의 흐름은 자연에서 순차적이며 서로 동시에 실행될 수있는 처리 단계로 분할됩니다.
Flowable . range ( 1 , 10 )
. observeOn ( Schedulers . computation ())
. map ( v -> v * v )
. blockingSubscribe ( System . out :: println );
이 예제는 계산 Scheduler
에서 1에서 10까지의 숫자를 제곱하고 "기본"스레드에서 결과를 소비합니다 (보다 정확하게는 blockingSubscribe
의 발신자 스레드). 그러나 Lambda v -> v * v
이 흐름에 대해 병렬로 실행되지 않습니다. 동일한 계산 스레드에서 값 1 ~ 10을받습니다.
1 ~ 10을 병렬로 처리하는 것은 조금 더 관련이 있습니다.
Flowable . range ( 1 , 10 )
. flatMap ( v ->
Flowable . just ( v )
. subscribeOn ( Schedulers . computation ())
. map ( w -> w * w )
)
. blockingSubscribe ( System . out :: println );
실제로, Rxjava의 병렬 처리는 독립적 인 흐름을 실행하고 결과를 단일 흐름으로 다시 병합하는 것을 의미합니다. 연산자 flatMap
먼저 각 번호를 1 ~ 10의 개별 Flowable
에 매핑하여이를 수행하여 실행하여 계산 된 사각형을 병합합니다.
그러나 flatMap
은 주문을 보장하지 않으며 내부 흐름의 항목은 인터리브 될 수 있습니다. 대체 운영자가 있습니다.
concatMap
concatMapEager
그러나 출력 흐름은 그 내부 흐름이 생성 된 순서입니다. 또는 Flowable.parallel()
연산자 및 ParallelFlowable
유형은 동일한 병렬 처리 패턴을 달성하는 데 도움이됩니다.
Flowable . range ( 1 , 10 )
. parallel ()
. runOn ( Schedulers . computation ())
. map ( v -> v * v )
. sequential ()
. blockingSubscribe ( System . out :: println );
flatMap
은 강력한 연산자이며 많은 상황에서 도움이됩니다. 예를 들어, Flowable
을 반환하는 서비스가 주어지면 첫 번째 서비스에서 방출되는 값으로 다른 서비스를 호출하고 싶습니다.
Flowable < Inventory > inventorySource = warehouse . getInventoryAsync ();
inventorySource
. flatMap ( inventoryItem -> erp . getDemandAsync ( inventoryItem . getId ())
. map ( demand -> "Item " + inventoryItem . getName () + " has demand " + demand ))
. subscribe ( System . out :: println );
때로는 항목을 사용할 수있게되면 일부 종속 계산을 수행하고 싶습니다. 이는 때때로 연속화 라고 불리며 어떤 일이 발생 해야하는지에 따라 어떤 유형이 관련되어 있는지에 따라 다양한 운영자가 달성 할 수 있습니다.
가장 일반적인 시나리오는 값을주고, 다른 서비스를 호출하고, 기다렸다가 결과를 계속하는 것입니다.
service . apiCall ()
. flatMap ( value -> service . anotherApiCall ( value ))
. flatMap ( next -> service . finalCall ( next ))
또한 나중에 시퀀스가 이전 매핑의 값을 요구하는 경우가 종종 있습니다. 이것은 외부 flatMap
이전 flatMap
의 내부 부분으로 옮기면 달성 할 수 있습니다.
service . apiCall ()
. flatMap ( value ->
service . anotherApiCall ( value )
. flatMap ( next -> service . finalCallBoth ( value , next ))
)
여기서 원래 value
Lambda 변수 캡처로 제공되는 Inner flatMap
내부에서 사용할 수 있습니다.
다른 시나리오에서, 첫 번째 소스/데이터 흐름의 결과는 관련이 없으며 다른 소스를 계속하고 싶습니다. 여기서는 flatMap
도 다음과 같이 작동합니다.
Observable continued = sourceObservable . flatMapSingle ( ignored -> someSingleSource )
continued . map ( v -> v . toString ())
. subscribe ( System . out :: println , Throwable :: printStackTrace );
그러나이 경우의 연속은 더 적절한 Single
대신 Observable
합니다. (이것은 flatMapSingle
의 관점에서, sourceObservable
다중 값 소스이므로 매핑은 여러 값을 초래할 수 있기 때문에 이해할 수 있습니다).
종종 중재자와 운영자 andThen
Completable
사용을 사용하여 다소 표현력이 뛰어나고 오버 헤드가 낮은 방법이 있습니다.
sourceObservable
. ignoreElements () // returns Completable
. andThen ( someSingleSource )
. map ( v -> v . toString ())
sourceObservable
과 someSingleSource
사이의 유일한 의존성은 후자를 소비하기 위해 전자가 정상적으로 완료해야한다는 것입니다.
때때로, 이전 시퀀스와 어떤 이유로 든 "일반 채널"을 통해 흐르지 않은 새로운 시퀀스 사이에는 암시 적 데이터 의존성이 있습니다. 하나는 다음과 같은 연속성을 작성하는 경향이 있습니다.
AtomicInteger count = new AtomicInteger ();
Observable . range ( 1 , 10 )
. doOnNext ( ignored -> count . incrementAndGet ())
. ignoreElements ()
. andThen ( Single . just ( count . get ()))
. subscribe ( System . out :: println );
불행히도,이 0은 Single.just(count.get())
이 데이터 플로우가 아직 실행되지 않은 조립 시간 에 평가되기 때문에 0
인쇄. 기본 소스가 완료 될 때 런타임 까지이 Single
소스의 평가를 방어하는 것이 필요합니다.
AtomicInteger count = new AtomicInteger ();
Observable . range ( 1 , 10 )
. doOnNext ( ignored -> count . incrementAndGet ())
. ignoreElements ()
. andThen ( Single . defer (() -> Single . just ( count . get ())))
. subscribe ( System . out :: println );
또는
AtomicInteger count = new AtomicInteger ();
Observable . range ( 1 , 10 )
. doOnNext ( ignored -> count . incrementAndGet ())
. ignoreElements ()
. andThen ( Single . fromCallable (() -> count . get ()))
. subscribe ( System . out :: println );
때로는 소스 또는 서비스가 작업 해야하는 흐름과 다른 유형을 반환합니다. 예를 들어, 위의 재고 예에서 getDemandAsync
Single<DemandRecord>
반환 할 수 있습니다. 코드 예제가 변경되지 않은 경우, 이로 인해 컴파일 타임 오류가 발생합니다 (종종 과부하 부족에 대한 오도 메시지가 오류 메시지가 표시됩니다).
이러한 상황에서는 일반적으로 변환을 수정하는 두 가지 옵션이 있습니다. 1) 원하는 유형으로 변환 또는 2) 다른 유형을 지원하는 특정 연산자의 과부하를 찾고 사용합니다.
각각의 반응성 기본 클래스는 프로토콜 변환을 포함하여 다른 유형과 일치하도록 이러한 변환을 수행 할 수있는 연산자를 특징으로합니다. 다음 행렬은 사용 가능한 변환 옵션을 보여줍니다.
흐름 | 주목할 만한 | 하나의 | 아마도 | 완성 가능 | |
---|---|---|---|---|---|
흐름 | toObservable | first , firstOrError , single , singleOrError , last , lastOrError 1 | firstElement , singleElement , lastElement | ignoreElements | |
주목할 만한 | toFlowable 2 | first , firstOrError , single , singleOrError , last , lastOrError 1 | firstElement , singleElement , lastElement | ignoreElements | |
하나의 | toFlowable 3 | toObservable | toMaybe | ignoreElement | |
아마도 | toFlowable 3 | toObservable | toSingle | ignoreElement | |
완성 가능 | toFlowable | toObservable | toSingle | toMaybe |
1 : 다중 값 소스를 단일 값 소스로 전환 할 때 결과로 많은 소스 값을 고려해야 할 많은 소스 값을 결정해야합니다.
2 : Observable
것을 Flowable
Observable
바꾸면 추가 결정이 필요합니다. BackpressureStrategy
매개 변수를 통해 또는 onBackpressureBuffer
, onBackpressureDrop
, onBackpressureLatest
와 같은 표준 Flowable
연산자를 통해 사용 가능한 몇 가지 전략 (예 : 버퍼링, 드롭, 최신 유지)이 있습니다.
3 : 최대 하나의 소스 항목 만 있으면 하류가 소비 할 준비가 될 때까지 항상 저장할 수 있으므로 배압에 문제가 없습니다.
자주 사용되는 많은 운영자는 다른 유형을 처리 할 수있는 과부하가 있습니다. 이들은 일반적으로 대상 유형의 접미사로 명명됩니다.
연산자 | 과부하 |
---|---|
flatMap | flatMapSingle , flatMapMaybe , flatMapCompletable , flatMapIterable |
concatMap | concatMapSingle , concatMapMaybe , concatMapCompletable , concatMapIterable |
switchMap | switchMapSingle , switchMapMaybe , switchMapCompletable |
이 연산자가 단순히 서명이 다른 이름을 갖지 않고 접미사를 갖는 이유는 유형 삭제입니다. Java operator
operator(Function<T, Single<R>>)
및 operator(Function<T, Maybe<R>>)
와 같은 서명을 고려하지 않습니다 (c#과 달리). 동일한 서명을 가진 중복 방법으로.
프로그래밍의 이름 지정은 이름이 길고 표현력이 길고 포착되며 쉽게 기억에 남을 것으로 예상되는 가장 어려운 것 중 하나입니다. 불행히도, 대상 언어 (및 기존 규칙)는 이와 관련하여 너무 많은 도움을주지 않을 수 있습니다 (사용할 수없는 키워드, 유형 삭제, 유형 모호성 등).
원래 rx.net에서는 단일 항목을 방출 한 다음 완료 한 연산자를 Return(T)
라고합니다. Java 컨벤션은 소문자 이름을 메소드 이름을 시작하는 것이므로 Java의 키워드 인 return(T)
이되었을 것입니다. 따라서 Rxjava는이 연산자의 이름을 just(T)
선택했습니다. 연산자 Switch
에 대해서도 동일한 제한이 존재하며, switchOnNext
텍스트로 명명되어야합니다. 또 다른 예는 onErrorResumeNext
로 명명 된 Catch
입니다.
Function<T, X>
주위의 유형 삭제가 그러한 메소드 서명을 복제로 바꾸기 때문에 사용자가 반응 유형을 반환하는 기능을 제공 할 것으로 기대하는 많은 연산자. Rxjava는 유형을 접미어로 추가하여 그러한 연산자의 이름을 지정하기로 결정했습니다.
Flowable < R > flatMap ( Function <? super T , ? extends Publisher <? extends R >> mapper )
Flowable < R > flatMapMaybe ( Function <? super T , ? extends MaybeSource <? extends R >> mapper )
특정 연산자는 유형 삭제에서 문제가 없지만 특히 Java 8 및 Lambdas를 사용하는 경우 서명이 모호 할 수 있습니다. 예를 들어, 기본 구현에서 편의성 및 성능 이점을 제공하기 위해 다양한 다른 반응성베이스 유형을 concatWith
로 취하는 몇 가지 과부하가 있습니다.
Flowable < T > concatWith ( Publisher <? extends T > other );
Flowable < T > concatWith ( SingleSource <? extends T > other );
Publisher
와 SingleSource
는 기능적 인터페이스 (하나의 추상 방법을 가진 유형)로 나타나며 사용자가 Lambda 표현식을 제공하도록 권장 할 수 있습니다.
someSource . concatWith ( s -> Single . just ( 2 ))
. subscribe ( System . out :: println , Throwable :: printStackTrace );
불행히도,이 접근법은 작동하지 않으며 예제는 2
전혀 인쇄하지 않습니다. 실제로, 버전 2.1.10 이후, 과부하 concatWith
존재하고 컴파일러가 모호한 코드를 찾기 때문에 컴파일되지 않습니다.
그러한 상황의 사용자는 아마도 someSource
완료 될 때까지 계산을 연기하고 싶었을 것입니다. 따라서 올바른 명백한 운영자는 defer
같습니다.
someSource . concatWith ( Single . defer (() -> Single . just ( 2 )))
. subscribe ( System . out :: println , Throwable :: printStackTrace );
때로는 접미사가 추가되어 컴파일 할 수 있지만 흐름에서 잘못된 유형을 생성하는 논리적 모호성을 피합니다.
Flowable < T > merge ( Publisher <? extends Publisher <? extends T >> sources );
Flowable < T > mergeArray ( Publisher <? extends T >... sources );
기능 인터페이스 유형이 유형 인수 T
로 관여 할 때도 모호 할 수 있습니다.
데이터 플로우는 실패 할 수 있으며,이 시점에서 오류는 소비자에게 방출됩니다. 그러나 때로는 여러 소스가 실패 할 수 있습니다. 그 시점에서 모든 소스가 모두 완료되거나 실패하기를 기다리는 지 여부가 선택할 수 있습니다. 이 기회를 나타내려면 많은 연산자 이름이 DelayError
에너로 단어로 접미사를받습니다 (다른 하나는 delayError
또는 delayErrors
부울 플래그가 과부하 중 하나에 있습니다).
Flowable < T > concat ( Publisher <? extends Publisher <? extends T >> sources );
Flowable < T > concatDelayError ( Publisher <? extends Publisher <? extends T >> sources );
물론 다양한 종류의 접미사가 함께 나타날 수 있습니다.
Flowable < T > concatArrayEagerDelayError ( Publisher <? extends T >... sources );
기본 클래스는 수많은 정적 및 인스턴스 메소드로 인해 무거운 것으로 간주 될 수 있습니다. Rxjava 3의 디자인은 반응성 스트림 사양에 의해 크게 영향을 받았기 때문에 라이브러리에는 각 반응 유형 별 클래스 및 인터페이스가 있습니다.
유형 | 수업 | 인터페이스 | 소비자 |
---|---|---|---|
0..n 배압 | Flowable | Publisher 1 | Subscriber |
0..n 비 동요 | Observable | ObservableSource 2 | Observer |
1 요소 또는 오류 | Single | SingleSource | SingleObserver |
0..1 요소 또는 오류 | Maybe | MaybeSource | MaybeObserver |
0 요소 또는 오류 | Completable | CompletableSource | CompletableObserver |
1 org.reactivestreams.Publisher
외부 반응 스트림 라이브러리의 일부입니다. 반응성 스트림 사양에 의해 관리되는 표준화 된 메커니즘을 통해 다른 반응성 라이브러리와 상호 작용하는 것이 주요 유형입니다.
2 인터페이스의 이름 지정 규칙은 Source
반 전통 클래스 이름에 추가하는 것이 었습니다. Publisher
Reactive Streams Library에서 제공하기 때문에 FlowableSource
없습니다 (및 상호 작용에 도움이되지 않았을 것입니다). 그러나 이러한 인터페이스는 반응 스트림 사양의 의미에서 표준이 아니며 현재 Rxjava 특이 적입니다.
기본적으로 Rxjava 자체는 Proguard/R8 설정이 필요하지 않으며 문제없이 작동해야합니다. 불행하게도, 버전 1.0.3 이후의 반응성 스트림 의존성은 JAR에 Java 9 클래스 파일을 내장하여 일반 대리자와의 경고를 유발할 수 있습니다.
Warning: org.reactivestreams.FlowAdapters$FlowPublisherFromReactive: can't find superclass or interface java.util.concurrent.Flow$Publisher
Warning: org.reactivestreams.FlowAdapters$FlowToReactiveProcessor: can't find superclass or interface java.util.concurrent.Flow$Processor
Warning: org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber: can't find superclass or interface java.util.concurrent.Flow$Subscriber
Warning: org.reactivestreams.FlowAdapters$FlowToReactiveSubscription: can't find superclass or interface java.util.concurrent.Flow$Subscription
Warning: org.reactivestreams.FlowAdapters: can't find referenced class java.util.concurrent.Flow$Publisher
응용 프로그램의 proguard-ruleset
파일에 다음 -dontwarn
항목을 설정하는 것이 좋습니다.
-dontwarn java.util.concurrent.Flow*
R8의 경우, RXJava JAR에는 동일한 경고 조항이있는 META-INF/proguard/rxjava3.pro
포함되어 있으며 자동으로 적용되어야합니다.
자세한 내용은 위키를 참조하십시오.
버전 3.x가 개발 중입니다. 버그 문제는 2.x 및 3.x 분기에 모두 적용되지만 새로운 기능은 3.x에만 추가됩니다.
사소한 3.x 증분 (예 : 3.1, 3.2 등)은 사소하지 않은 새로운 기능이 추가되거나 중요한 향상 또는 버그 수정이 발생하면 일부 에지 케이스에 영향을 줄 수있는 행동 변화가있을 수 있습니다 (예 : 행동에 대한 의존성과 같은 행동 변화가 발생할 수 있습니다. 버그). 이로 인해 분류 될 향상의 예는 이전에이를 지원하지 않은 연산자에게 반응성 풀압 지지대를 추가하는 것입니다. 이것은 거꾸로 호환되어야하지만 다르게 행동합니다.
패치 3.xy 증분 (예 : 3.0.0-> 3.0.1, 3.3.1-> 3.3.2 등)은 버그 수정 및 사소한 기능 (메소드 오버로드 추가)에서 발생합니다. 패치 릴리스에 @Beta
또는 @Experimental
주석으로 표시된 새로운 기능을 추가하여 불안정한 새로운 기능을 빠르게 탐색하고 반복 할 수 있습니다.
클래스 또는 메소드 레벨에서 @Beta
주석으로 표시된 API는 변경 될 수 있습니다. 어떤 식 으로든 수정하거나 언제든지 제거 할 수 있습니다. 코드가 라이브러리 자체 인 경우 (예 : 컨트롤 이외의 사용자의 클래스 경로에서 사용되는 경우) 베타 API를 다시 포장하지 않으면 (예 : Proguard, Shading 등) 베타 API를 사용해서는 안됩니다.
클래스 또는 메소드 레벨에서 @Experimental
주석으로 표시된 API는 거의 확실하게 변경됩니다. 어떤 식 으로든 수정하거나 언제든지 제거 할 수 있습니다. 프로덕션 코드에서 사용하거나 의존해서는 안됩니다. 그들은 순전히 광범위한 테스트와 피드백을 허용합니다.
클래스 또는 메소드 레벨에서 @Deprecated
주석이 표시된 API는 다음 주요 릴리스까지 지원되지만 사용을 중단하는 것이 좋습니다.
io.reactivex.rxjava3.internal.*
패키지는 개인 API로 간주되며 전혀 의존해서는 안됩니다. 언제든지 변경 될 수 있습니다.
http://reactivex.io/RxJava/3.x/javadoc/3.xy/
Maven, Ivy, Gradle 등의 바이너리 및 의존성 정보는 http://search.maven.org에서 찾을 수 있습니다.
Gradle의 예 :
implementation ' io.reactivex.rxjava3:rxjava:x.y.z '
그리고 Maven의 경우 :
< dependency >
< groupId >io.reactivex.rxjava3</ groupId >
< artifactId >rxjava</ artifactId >
< version >x.y.z</ version >
</ dependency >
그리고 아이비에게 :
< dependency org = " io.reactivex.rxjava3 " name = " rxjava " rev = " x.y.z " />
2021 년 5 월 1 일 이후의 스냅 샷은 https://oss.sonatype.org/content/repositories/snapshots/io/reacitive/rxjava3/rxjava/를 통해 제공됩니다.
repositories {
maven { url ' https://oss.sonatype.org/content/repositories/snapshots ' }
}
dependencies {
implementation ' io.reactivex.rxjava3:rxjava:3.0.0-SNAPSHOT '
}
Javadoc 스냅 샷은 http://reacitivex.io/rxjava/3.x/javadoc/snapshot에서 제공됩니다
구축하려면 :
$ git clone [email protected]:ReactiveX/RxJava.git
$ cd RxJava/
$ ./gradlew build
건물에 대한 자세한 내용은 위키의 시작 페이지에서 찾을 수 있습니다.
버그, 질문 및 토론은 Github 문제를 사용하십시오.
Copyright (c) 2016-present, RxJava Contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.