[android] RxAndroid 맛보기
http://www.vogella.com/tutorials/RxJava/article.html
https://code.tutsplus.com/tutorials/getting-started-with-reactivex-on-android--cms-24387
https://realm.io/kr/news/rxandroid/
-
Observable.just() 는 Observable 을 생성한다.
이렇게 생성된 Observable 에 subscribe 가 붙으면 곧바로 just() 에 전달된 녀석이 onNext() 로 전달된다.
List<String> list = Arrays.asList(“Android”, “Ubuntu”, “Mac OS”);
Observable<List<String>> listObservable = Observable.just(list);
listObservable.subscribe(new Observer<List<String>>(){ // returns Subscription object
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(List<String> list) {
System.out.println(list);
}
});
Output
Android
Ubuntu
Mac OS
-
onCompleted 와 onError 는 자주 안 쓰이기 때문에 Action1 interface 를 사용하는 경우가 많다.
Action1<List<String>> myAction = new Action1<>(){
@Override
public void call(List<String> list){ // onNext 와 동일한 녀석이라 보면 된다.
// do something..
}
}
listObservable.subscribe(myAction); // subscribe 의 다음에 error, complete 에 대한 action 을 추가할 수 있다.
-
onError 에 대한 subscriber 는 Action1<Throwable> 이고, onComplete 에 대한 subscriber 는 Action0 이다.
-
Observable.from() 는 from 에 들어가는 녀석에 대해 element 를 순차적으로 1개씩 받을 수 있는 구조가 된다.
List<String> list = Arrays.asList(“Hello”, “Streams”, “Not”);
Observable.from(list)
.subscribe(new Action1<String>(){
@Override
public void call(String element){
// do something
}
});
-
Subscription object 가 있으면 data 가 emit 되는 와중에 unsubscribe() 함수를 통해 unsubscribe 할 수 있다.
mySubscription.unsubscribe();
-
map, filter 는 array 와 같은 녀석들에 조건처리를 하기에 좋다.
Rx 함수들은 대부분 새로운 Observable 을 return 하여 chaining 해서 사용하기에 좋다.
listObservable.skip(2) // 앞의 2개는 무시한다.
.map(new Func1<String, String>(){
@Override
public String call(String str){
return str.toUpperCase();
}
})
.filter(new Func1<String, Boolean>(){
@Override
public Boolean call(String string){
return string.startsWith(“a”);
}
})
.subscribe( … );
위 함수는 아래와 같이 lamda 를 사용해 변형될 수 있다.
listObservable.skip(2)
.map( s -> s.toUpperCase() )
.filter( s -> s.startsWith(“a”) )
.subscribe( … )
-
Observable 은 async job 을 사용하기에 좋다.
이는 subscribeOn 과 observeOn 을 통해 이루어진다.
subscribeOn 은 Observer 에서 작업하는 thread 를 지정하고,
observeOn 에서는 subscriber 가 불리는 thread 를 지정한다.
Observable<String> fetchFromGoogle = Observable.create(new Observable.OnSubscribe<String>(){
@Override
public void call(Subscriber<? super String> subscriber){
try{
String data = fetchData(“http://www.google.com”);
subscriber.onNext(data);
subscriber.onCompleted();
}catch(Exception e){
subscriber.onError(e);
}
}
});
fetchFromGoogle.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>(){
@Override
public void call(String s){
// do something..
}
});
-
RxJava 를 사용하면 여러 개의 Thread 를 사용할 때 다음과 같이 편하게 사용할 수 있다.
zip 은 병렬 동작을 한 후 결과를 모아주는 데 사용할 수 있다.
Observable<String> zipped = Observable.zip(fetchFromGoogle, fetchFromYahoo, new Func2<String, String, String>(){
@Override
public String call(String google, String yahoo){
return google + “\n” + yahoo;
}
});
순차적인 처리는 아래와 같이 할 수 있다.
Observable<String> concatenated = Observable.concat(fetchFromGoogle, fetchFromYahoo);
-
RxAndroid 에는 ViewObservable 이 있고, 이 녀석은 View 의 event handling 을 수월하게 해준다.
Observable<OnClickEvent> clicksObservable = ViewObservable.clicks(myButton);
clicksObservable.skip(4)
.subscribe(e -> Log.d(“clicked!”))
-
Lamda expression 을 사용할 때 타입 추론을 할 수 있다면 추론을 생략할 수 있다.
람다의 단점은 자바8 이상부터 쓸 수 있다는 것이다.
안드로이드는 자바 8을 지원하지 못해 람다를 쓰기 위해서는 이전 버전에서 람다를 쓸 수 있게 하는 포팅 라이브러리를 사용해야 하며, 알맞은 라이브러리는 레트로람다(Retrolambda) 이다.
.map((String text) -> { … })
.map((text) -> { … })
.map(text -> …) // 인자가 하나인 경우 생략 가능하다, 블록 내 문장이 하나이고 리턴값을 갖는다면 블록, 세미콜론, 리턴 키워드를 다 지울 수 있다.
-
RxAndroid 는 Click 의 추상화에 좋다.
RxView.clicks(findViewbyId(R.id.button))
.map(event -> new Random().nextInt())
.subscribe(value ->{
// do something on view
}, throwable -> {
// error handling
});
두 event 에 대해 한 처리를 하려면…
Observable<String> leftBtnObservable = RxView.clicks(findViewById(R.id.leftBtn)).map(event -> “left” );
Observable<String> rightBtnObservable = RxView.clicks(findViewById(R.id.rightBtn)).map(event -> “right” );
Observable.merge(leftBtnObservable, rightBtnObservable)
.subscribe( string -> {
// do something
});
-
chain function 에 기존에 존재하는 함수를 대입하려면.. ( 메서드 레퍼런스 )
public static boolean isEmpty(CharSequence sequence) {
return sequence.length() != 0;
}
RxTextView.text(editText1)
.map(MainActivity::isEmpty);
-
combineLatest 는 전달되는 Observable 의 값이 변경될 때마다 뒤의 람다 함수가 호출된다.
textValidation1 = Observable.combineLatest(checks1, textExist1, (check, exist) -> !check || exist );
-
RxJava 스케쥴러 목록은 다음과 같다.
Schedulers.computation() // 간단한 연산이나 콜백 처리
Schedulers.from(executor) // 특정 executor 를 스케쥴러로
Schedulers.immadiate() // 현재 스레드
Schedulers.io() // 동기 I/O 를 별도로 처리시켜 비동기 효율을 얻기 위한 스케쥴러, 자체적인 스레드 풀에 의존
Schedulers.newThread() // 항상 새로운 thread
Schedulers.trampoline() // 큐에 있는 일이 끝나면 이어서 현재 스레드에서 수행하는 스케쥴러
일부 operator 들은 자체적으로 어떤 스케쥴러를 사용할지 지정한다.
예를 들어 buffer 는 computation 에 의존하며 repeat 은 trampoline 을 사용한다.
RxAndroid 에는 다음 2가지가 더 있다.
AndroidSchedulers.mainThread() // main thread
HandlerScheduler.from(handler) // 특정 handler 의 thread
보통 async task 를 할 때 io 를 사용해서 bg 동작을 하고, mainThread 를 이용해 결과를 전달한다.
-
RxJava 의 operatoin 들은 아래 링크를 참조한다.
http://reactivex.io/documentation/operators.html
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] png 기반 GIF 를 바탕으로 VectorDrawable 로 치환해 animation 만들기 (0) | 2018.03.12 |
---|---|
[android] library 를 dependency 에 명시할 수 있게 배포하기 (0) | 2018.03.11 |
[android] RxJava가 뭐야? 맛보기! (0) | 2018.03.09 |
[Android Studio] Crash 났을 때 Log 날아가지 않도록 하기 (0) | 2018.03.08 |
[android] 최고의 안드로이드 개발 원칙 (2) | 2018.03.07 |
댓글