COCSOS - guitar, computer, etc
181004 RxJava2+Retrofit2+lambda정리 본문
RxJava를 앱에 적용하려고하는데 RxJava와 RxAndroid 의 차이점이 궁금해짐..
RxJava와 RxAndroid
RxAndroid는 RxJava를 사용하기 쉽게 추가된 확장팩 같은 것이라고 하면 된다. 메인 스레드 스케줄러 등을 제공한다고?
This module adds the minimum classes to RxJava that make writing reactive components in Android applications easy and hassle-free. More specifically, it provides a Scheduler that schedules on the main thread or any given Looper.
FROM : https://stackoverflow.com/questions/49651249/difference-between-rxjava-and-rxandroid
+ https://github.com/ReactiveX/RxAndroid
rxjava가 뭔지는 이 사이트에 잘 설명이 되어있다. 항상 애용하는 곳
FROM : https://www.charlezz.com/?p=189
아무튼 이전 포스트엔 retrofit2를 이용하여 interface에서 정의한 함수를 실행하여 call 객체를 받았다.
받은 Call 객체에서 제공하는 메소드인 .enqueue(콜백추가) // 백그라운드 스레드에서 실행
혹은 .execute() // 현재 스레드에서 실행
를 사용해서 서버에 get,post 메세지를 보내고, 데이터를 받아올 수 있었다.
이제 여기에 rxjava를 추가하려고 한다.
우선 정의했던 interface 내부 함수
@GET("/users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
의 반환형 Call<List<Repo>>을 Observable<List<Repo>> 로 바꾸어주어야 한다.
그러기 위해선 gson으로 컨버팅 할 때 그래들에 추가해줬던 것과 마찬가지로
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
을 gradle에 추가해주어야한다.
참고로 Observable<Repo> 는 Repo 하나에 대해서, Observable<List<Repo>>는 여러개의 객체 배열에 대해서 받아온 것.
Observable은 데이터 자체라기보단 스트림...즉 "데이터가 계속 지나갈 강물"이라고 말하는 편이 편했다.
왠지 발행emit과 소비consume, 구독같은 표현은 삘이 잘 안와서...
아무튼
Observable<List<Repo>> reposObservable = listRepos("유저 이름");
로 Observable을 받아왔다. Observable이라는 Stream, 강물 속에서 아이템은 처리되길 기다리면서 흘러가고있다.
이걸 건져야 사용하든 할텐데, 건지는것을 Subscription 구독이라고 함.
구독을 요청할 때 처리절차를 넣어야되는데 처리절차를 정하는 클래스를 Observer라고 하고 어디는 Action1 등등 하는 용어가 많다.
.subscribe()하는 행위가 구독이며, 구독한 결과의 반환 클래스 이름이 rxJava1에서는 Subscription이라고 했는데 rxJava2에서는 Disposable라고 바뀌었다.
상세한 처리절차는 .subcribe() 함수 내부에 정의한다.
.subscribe(내부에서 처리할 콜백이 담겨있는 Subject 클래스); // onNext(),onComplete(),onError()의 처리 등!
혹은 간단하게 처리만 하려면
.subscribe( Consumer 클래스); //
ex)
.subscribe(new Consumer<String>() {
@Override public void accept(List<Repo> repos) {
//데이터의 처리
Log.d(repos.toString());
}
});
를 구현할 수 있다.
자바는 불편한것이
그런데... .subscribe() 내부에 익명 클래스를 넘겨준다. 넘나 소비적인 귀찮은 짜증나는 복합한 것
사용자는 무슨 함수를 사용하는지만 넘기면 되는데 말이다.
여기서 lambda가 등장하여 코드를 간결하게 만든다.
.subscribe(repos-> Log.d(repos.toString()));
자바에서는 함수가 없고 메소드라는 이름으로 존재하므로 메소드를 가지고있는 인터페이스 형식으로 람다가 구현된다고.. 카더라
아무튼
.subscribe(list->list의 처리)
.subscribe(list->{
여러줄일때는;
중괄호를 사용하여;
list의 처리;})
처럼 사용할 수 있고 처리가 하나있는 (onNext()) Consumer만 사용하면 에러날때 처리를 못한다고 하니까
.subscribe(list->list처리) ,error->error.printStackTrace()} 로 구현해준다.
함수를 두개받는 클래스인 Consumer({onNext(),onError()})를 람다가 잘 구현해준다.
함수 이름,변수명을 입력할 필요가 없다니; 충격; 타입 추론 짱짱맨이야
이렇게 어떻게 처리하는지도 정했다.
이제, 어느 스레드에서 작동시킬지를 정해야함.
그러려면 subscribeOn과 observeOn을 구분할 줄 알아야한다.
SubscribeOn과 ObserveOn은 어떻게 다를까?
subscribeOn은 어느 스레드에서 기다릴지, ObserveOn은 결과를 어디서 볼 지(어디서 처리할 지)를 묻는 것 같다.
.subscribeOn(Schedulers.io()) //백그라운드
.observeOn(AndroidSchedulers.mainThread()) // 메인 스레드. UI 스레드
.subscribe()...
그래서 인터넷 연결은 이런 코드가 많다. *AndroidSchedulers 는 rxAndroid를 gradle에 추가해야있는 클래스다.
이 경우에는 아이템이 떠다니는 강물을 백그라운드로 지나가게 subscribeOn하고, 건져서 처리하는 것은 mainThread에서 처리하겠다는 말이 된다고/
SubscribeOn specify the Scheduler on which an Observable will operate. ObserveOn specify the SchedulerSub on which an observer will observe this Observable.
So basically SubscribeOn is mostly subscribed (executed) on a background thread ( you do not want to block the UI thread while waiting for the observable) and also in ObserveOn you want to observe the result on a main thread...
If you are familiar with AsyncTask then SubscribeOn is similar to doInBackground method and ObserveOn to onPostExecute.
Schedulers.computation()는 cpu가 필요한 백그라운드 워크, 예를 들면 막대한 양의 계산이나 비트맵 계산들에 쓰임 unbounded thread pool
Schedulers.io()는 파일 시스템 저장이나 네트워크 호출 등에 쓰인다
'Computer > android' 카테고리의 다른 글
220405 애니메이션 훑기 (0) | 2022.04.05 |
---|---|
191205 App Widget 정리 - 1 (0) | 2019.12.05 |
181002 Retrofit2 설명, 차이와 사용법 (0) | 2018.10.04 |