RxJava가 편하다고 말만듣고 해야지해야지 하다가 어려워 보여서 안하고 있었는데, 써보니 편한 게 많다.
글로만 읽었을 땐 이해가 안됐는데, 직접 해보니 감이 오더라.
읽어보면 도움되는 곳
- https://github.com/ReactiveX/RxJava/wiki
- http://rxmarbles.com
- http://chuumong.tistory.com/entry/RxJava-정리
- https://realm.io/kr/news/rxandroid/
- http://pluu.github.io/blog/rx/2015/04/29/rxjava/
정렬
Integer[] intList = {6, 1, 3, 5, 7, 0, -3}; Observable.from(intList).toSortedList().subscribe(n -> Log.i("int sort 1 ", "|" + n)); // int sort 1: |[-3, 0, 1, 3, 5, 6, 7] Observable.from(intList).toSortedList((i1, i2) -> i1.compareTo(i2)).subscribe(n -> Log.i("int sort 2 ", "|" + n)); // int sort 2: |[-3, 0, 1, 3, 5, 6, 7] Observable.from(intList).toSortedList((i1, i2) -> -i1.compareTo(i2)).subscribe(n -> Log.i("int sort 3 ", "|" + n); // int sort 3: |[7, 6, 5, 3, 1, 0, -3]
String[] strList = {"o", "T", "가나다", "a", "b", "c", "z", "h", "Q", "R", "토요일"}; Observable.from(strList).toSortedList().subscribe(n -> Log.i("str sort 1 ", "|" + n)); // str sort 1: |[Q, R, T, a, b, c, h, o, z, 가나다, 토요일] Observable.from(strList).toSortedList((s1, s2) -> s1.compareTo(s2)).subscribe(n -> Log.i("str sort 2 ", "|" + n)); // str sort 2: |[Q, R, T, a, b, c, h, o, z, 가나다, 토요일] Observable.from(strList).toSortedList((s1, s2) -> -s1.compareTo(s2)).subscribe(n -> Log.i("str sort 3 ", "|" + n)); // str sort 3: |[토요일, 가나다, z, o, h, c, b, a, T, R, Q]
first, last, take, takeLast
String[] strings = new String[0]; Observable.from(strings).first().subscribe(s -> Log.i("empty ", "|" + s)); // rx.exceptions.OnErrorNotImplementedException: Sequence contains no elements
처음과 마지막을 가져오는 first(), last() 가 있는데, 빈 배열일 때 호출하면 오류가 난다.
String[] strings = new String[0]; Observable<String> so = Observable.from(strings); Log.i("=", "=== 1 === "); so.take(1).subscribe(s -> Log.i("empty array 1 ", "|" + s)); Log.i("=", "=== 2 === "); so.takeLast(1).subscribe(s -> Log.i("empty array 2 ", "|" + s)); Log.i("=", "=== 3 === "); so.first().subscribe(s -> Log.i("empty array 3 ", "|" + s), e -> {}, () -> {}); Log.i("=", "=== end === "); // === 1 === // === 2 === // === 3 === // === end ===
first 대신 take(1), last 대신 takeLast(1)을 쓰거나, subscribe에 onError, onCompleted 를 적어주면 된다.
flatmap
ruby의 flatten 같은 느낌인데, 변환과정에서 배열로 리턴된걸 다시 observable로 만들어 준다.
String str = "qwer-asdf-zxcv"; Observable.just(str) .map(s -> s.split("-")) .flatMap(Observable::from) .take(2) .takeLast(1) .subscribe(s -> Log.i("split", "|" + s)); // split: |asdf
비동기
Observable.range(1, 9999).subscribe(t -> {}, e -> {}, () -> Log.i("", "9999 끝")); Observable.range(1, 100).subscribe(t -> {}, e -> {}, () -> Log.i("", "100 끝")); // 9999 끝 // 100 끝
그냥 이렇게 하면 일반적인 동작을 한다.
Observable.range(1, 9999).subscribeOn(Schedulers.newThread()).subscribe(t -> {}, e -> {}, () -> Log.i("", "9999 끝")); Observable.range(1, 100).subscribeOn(Schedulers.newThread()).subscribe(t -> {}, e -> {}, () -> Log.i("", "100 끝")); // 100 끝 // 9999 끝
subscribeOn(Schedulers.newthread()) 를 달아주면 비동기로 호출이 된다.
observeOn
만약 비동기 혹은 다른 이유로 뷰를 건들일 때
Observable.just("111").subscribeOn(Schedulers.newThread()).subscribe(t -> tv.setText(t)); // rx.exceptions.OnErrorNotImplementedException: Only the original thread that created a view hierarchy can touch its views.
라는 에러가 나면
.observeOn(AndroidSchedulers.mainThread())
를 붙여주면 된다.
Observable.just("111").subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(t -> tv.setText(t));
================ 여기서 부터는 RxJava 2.x 로 작성됨 ============
groupBy
배열에서 고유한 값만 가져오고 있을 때 사용하면 좋다. 특히 날짜별로 정렬할 때 사용하면 아주 편하다.
private void groupBy() { Integer[] array = {1, 1, 1, 2, 3, 4, 5, 6, 6, 4, 34, 3, 2, 1}; Observable<Integer> ob = Observable.fromArray(array); Observable ob2 = ob.groupBy((Function<Integer, Object>) i -> i).map(i -> i.getKey()); ob2.subscribe(i -> Log.i("MainActivity : groupBy", "고유값 " + i)); // 고유값 1 // 고유값 2 // 고유값 3 // 고유값 4 // 고유값 5 // 고유값 6 // 고유값 34 ob2.subscribe(i -> { Log.i("MainActivity : groupBy", "=======" + i + "=========="); ob.filter(i::equals) .subscribe(i2 -> Log.i("MainActivity : groupBy", "filter: " + i2.toString())); }); // =======1========== // filter: 1 // filter: 1 // filter: 1 // filter: 1 // =======2========== // filter: 2 // filter: 2 // =======3========== // filter: 3 // filter: 3 // =======4========== // filter: 4 // filter: 4 // =======5========== // filter: 5 // =======6========== // filter: 6 // filter: 6 // =======34========== // filter: 34 }