본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] RxAndroid 맛보기

by 돼지왕 왕돼지 2018. 3. 10.
반응형

[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/

Action, action0, action1, action1 interface, Android, androidscheduler, androidschedulers, async job, async task, Buffer, Call, chain function, chaning, combinelatest, Computation, concat, CREATE, data, ELEMENT, emit, executor, Filter, From, handler, handlerscheduler, immadiate, IO, java8, just, LAMBDA, mainthread, map, merge, method reference, newthread, observable, observable.from, observable.just, observeon, obsrveron, oncomplete, onerror, onnext, Operation, operator, ovservable, Repeat, retrolambda, rxandroid, rxjava, scheduler, Schedulers, skip, subscribe, subscribeon, subscriber, subscription object, thread, thread 지정, throwable, trampoline, type inference, unscribe, unsubscribe, view event handling, viewobservable, zip, [android] 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




반응형

댓글