본문 바로가기
Rx

안드로이드의 RxJava 활용 - 1 (Hello world,제어 흐름)

by 봄석 2018. 12. 28.

본 내용은 필자가 학습한 내용을 정리하는 내용입니다.

대부분 의 내용이 아래 책의 내용이므로 원서를 구매해서 직접보시는걸 추천드립니다!

RxJava 프로그래밍 리액티브 프로그래밍 기초부터 RxAndroid까지 한 번에

유동환 , 박정준 지음 | 한빛미디어 | 2017년 09월 04일 출간

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788968488658&orderClick=LAV&Kc=


저자님의 블로그

https://brunch.co.kr/@yudong#info




Hello world 예제

먼저  'Hello world'를 출력하는 간단한 프로그램을 작성해보겠습니다

Observable에서 문자를 입력받아 텍스트 뷰에 결과를 출력합니다.

public class HelloActivityV1 extends Activity {
    public static final String TAG = HelloActivityV1.class.getSimpleName();
    @BindView(R.id.textView) TextView textView;
 
    private Disposable mDisposable;
    private Unbinder mUnbinder;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mUnbinder = ButterKnife.bind(this);
 
        Observer<String> observable=new DisposableObserver<String>(){
            @Override
            public void onNext(String s) {
                textView.setText(s);
            }
 
            @Override
            public void onError(Throwable e) { }
            @Override
            public void onComplete() { }
        };
 
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("Hello world");
                e.onComplete();
            }
        }).subscribe(observable);
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (!mDisposable.isDisposed()) {
            mDisposable.dispose();
        }
        if (mUnbinder != null) {
            mUnbinder.unbind();
        }
    }

}


Observable.create()로 Observable을 생성해 "Hello world" 를 입력받고 subscribe() 함수

안 onNext() 함수에 전달합니다. onNext() 함수의 정의를 보면 마지막으로 전달된 문자를 텍스트뷰에 업데이트하게 되어 있습니다. 따라서 실제 구독자를 subscribe(observer)함수를 통해 등록하면 Hello world를 표시합니다.


람다 표현식으로 변형한 Hello world 예

Observable.<String>create(s->{
            s.onNext("Hello world!");
            s.onComplete();

        }).subscribe(o->textView.setText(o));


콜백함수를 람다 표현식으로 바꾸면서 데이터의 흐름이 명확해져 가독성이 좋아졌습니다.


전달자는 명확한 단어로 변경할 수도 있지만 기본적으로 이니셜을 많이 사용합니다.

다음은 just()함수를 사용한 코드입니다.

Observable.just("Hello world")
                .subscribe(textView::setText);


메소드 레퍼런스를 이용하여 Observable의생성 코드를 단순하게 했습니다.


제어 흐름

"for 문을 이해하려면 100가지 다른 방법으로 직접 코딩하고 비교해보라" 라는 이야기를 들어 본적이 있습니다. 쉽고 간단해 보이는 문법도 정확하게 구조를 알고 깊이 이해한 후 사용해야한다는 의미입니다.


조건문,순환문은 코드에서 가장 많은 비중을 차지합니다. 리액티브 프로그래밍의 세계에서도 예외는 아니지만 구현 방법이 다릅니다. RxJava에서 제공하는 리액티브 연산자를 이용합니다.


자바와 RxJava 버전별로 제어 흐름 구현을 비교한 것입니다. Iterable 객체에서 apple을 찾으면 'apple'을 출력하고 그렇지 않으면 'Not found'를 출력하는 코드입니다.


제어 흐름 구현 비교 예

Iterable<String> samples = Arrays.asList(
            "banana","orange","apple","apple mango","melon","watermelon"); 
//자바
    @OnClick(R.id.btn_loop)
    void loop(){
        log(">>>>> get an apple::java");
        for(String s: samples){
            if(s.contains("apple")){
                log(s);
                return;
            }
        }
    }
    /*
    @OnClick(R.id.btn_loop2)
    void loop2() {
        log(">>>>> get an apple :: rx 1.x");
        //rxJava 1.x
        rx.Observable.from(samples)
                .filter(s -> s.contains("apple"))
                .firstOrDefault("Not found")
                .subscribe(this::log);
    }*/
 
 
    @OnClick(R.id.btn_loop3)
    void loop3(){
        log(">>>>>>get an apple :: rx 2.x");
 
        //rxJava 2.x
        Observable.fromIterable(samples)
                .skipWhile(s->!s.contains("apple"))
                .first("Not found")
                .subscribe(this::log);
    }



위 코드에서 주목해야 하는 부분은 Observable을 이용해 데이터를 발행하고 처리하는 기능에만 집중할 수 있게 된다는 것입니다. 코드를 살펴보면 smaples라는 스트림을 입력 받고 filter() 함수를 이용하여 'apple'가 아닌 값은 무시했습니다. filter() 함수를 통과한 값은 first() 함수로 첫 번째 값만 처리해 구독자에게 전달합니다. 즉, 기존 자바의 for문을 filer() 함수와 first() 함수로 대체했습니다.



댓글