Android/RxAndroid

RxAndroid

Ju_Hyang 2020. 5. 18. 22:59
 
  • RxAndroid란 ?
    • RxAndroid는 RxJava에 최소한의 클래스를 추가하여 안드로이드 앱에서 리액티브 구성요소를 쉽고 간편하게 사용하게 만드는 라이브러리 입니다.
    • 기존 안드로이드 개발에서 가장 어려움을 겪는 문제 중 하나는 복잡한 스레드 사용입니다. 복잡한 스레드 사용으로 발생하는 문제는 다음과 같습니다.
      • 안드로이드 비동치 처리 및 핸들링
      • 수많은 핸들러와 콜백 때문에 발생하는 디버깅 문제
      • 2개의 비동기 처리 후 결과를 하나로 합성하는 작업
      • 이벤트 중복 실행
    • RxAndroid는 습득하기 어려운 부분도 있지만 기존의 안드로이드 개발과 비교했을 때 장점이 많습니다. 다음 특징을 통해 앞 문제를 해결하는데 도움을 줍니다.
      • 간단한 코드로 복잡한 병행(concurrency) 프로그래밍을 할 수 있습니다.
      • 비동기 구조에서 에러를 다루기 쉽습니다.
      • 함수형 프로그래밍 기법도 부분적으로 적용할 수 있습니다.
 
  • 리액티브 라이브러리와 API
    • RxAndroid는 기본적으로 RxJava의 리액티브 라이브러리를 이용합니다. 안드로이드에서 사용하는 리액티브 API와 라이브러리는 상당히 많습니다. RxJava 1.x 이하 버전에서는 각종 컴포넌트의 이벤트 처리 부분도 하나의 라이브러리에 포함되어 있었습니다.
    • 하지만 경량화 작업과 유지보수 문제로 각 기능을 다른 라이브러리로 분리했습니다.
 
  • 안드로이드 스튜디오 환경 설정
    • 안드로이드 스튜디오는 빌드 도구로 그레이들을 이용합니다.
    • 따라서 리액티브 프로그래밍을 사용하려면 그레이들에서 리액티브 프로그래밍을 사용할 수 있도록 설정해야 합니다.
 
# build.gradle 설정
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
 
    //Rx Utils dependencies
    implementation 'io.reactivex.rxjava2:rxjava:2.1.3'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
 
    //RxLifecycle 2.x
    implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.1.0'
    implementation 'com.trello.rxlifecycle2:rxlifecycle:2.1.0'
    implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
 
    //Utils
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
    implementation 'com.jakewharton.timber:timber:4.4.0'
 
    //Utils - butter-knife
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
 
}
    • RxAndroid는 RxJava에 대한 의존성이 있어 RxJava를 추가하지 않아도 되지만, 최신 버전의 RxJava를 사용하려면 명시해주는것이 좋습니다.
 
  • RxAndroid의 기본
    • RxAndroid의 기본 개념은 RxJava와 동일합니다.
    • RxJava의 구조에 안드로이드의 각 컴포넌트를 사용할 수 있게 변경해 놓은 것입니다. 따라서 RxAndroid의 구성 요소는 다음처럼 RxJava의 구성요소와 같습니다.
      • Observable : 비즈니스 로직을 이용해 데이터를 발행합니다.
      • 구독자 : Observable에서 발행한 데이터를 구독합니다.
      • 스케줄러 : 스케줄러를 통해서 Observable, 구독자가 어느 스레드에서 실행될지 결정할 수 있습니다.
    • 이러한 과정을 간단한 코드로 나타내면 아래와 같습니다.
// 1. Observable 생성
Observable.create()
// 2. 구독자 이용
    .subscribe();
 
// 3. 스케줄러 이용
    .subscribeOn(Scheduler.io())
    .observeOn(AndroidSchedulers.mainThread())
 
    • Observable과 구독자가 연결되면 스케줄러에서 각 요소가 사용할 스레드를 결정하는 기본적인 구조입니다.
    • Observable이 실행되는 스레드는 subscribeOn() 함수에서 설정하고 처리된 결과를 onServeOn() 함수에 설정된 스레드로 보내 최종 처리 합니다.
      • AndroidScheduler.mainThread() - 안드로이드의 UI 스레드에서 동작하는 스케줄러 입니다.
      • HandlerScheduler.from(handler) - 특정 핸들러에 의존하여 동작하는 스케줄러 입니다.
 
 
안드로이드의 RxJava 활용 - 1 (Hello world, 제어 흐름)
 
  • Hello world 예제
    • 먼저 ‘Hello world’를 출력하는 간단한 프로그램을 작성해 보겠습니다.
    • Observable에서 문자를 입력받아 텍스트 뷰에 결과를 출력합니다.
public class HelloActivity1 extends Activity {
    public static final String TAG = HelloActivity1.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를 표시합니다.