-
안드로이드 비동기 처리 2-1 (RxJava & RxAndroid)안드로이드 학습/Android 기술면접 대비 2024. 8. 8. 09:45
안드로이드 비동기 Task를 처리할 때 주로 Thread와 Runnable등을 만들어서 처리했었다.
하지만 여러 기업들의 안드로이드 개발자 모집 요강에 보면 RxJava나 Coroutine의 경험을 필요로 한 것을 쉽게 볼 수 있다.
이것은 아마도 RxJava와 Coroutine만의 장점이 있기 때문이라고 생각한다.
그래서 먼저 RxJava 학습을 통해 좀 더 유연한 비동기 처리를 하기 위해서 학습을 시작하였다.
우선 RxJava, RxAndroid를 보면 공통적으로 보이는 것이 Rx다. 그래서 Rx가 무엇인지 먼저 알고 넘어가는 것이 필요할 것 같다.
1. RX란??
Rx란 Reactive Programming이다. 반응형 프로그래밍이라고도 한다.
반응형 프로그램이란 기존의 코드가 순서대로 실행되는 것과는 다르게 프로그램 자신이 주변 환경과 끊임없이 상호작용을 하면서 환경이 변하면 이벤트를 받아서 동작하는 프로그래밍 기법이다.
여기서 명령형 프로그래밍과 반응형 프로그래밍이라는 개념이 나온다.
명령형 프로그래밍(Imperative Programming) :
- 명령형 프로그래밍은 작성된 코드가 순서대로 실행되는 방식의 프로그래밍이다. 코드가 순서대로 실행되는 것은 개발자가 작성한 조건문, 반복문 또는 함수 호출 등에 의해 컴파일러가 다른 코드로 이동하는 것을 의미합니다.
반응형 프로그래밍 (Reactive Programming)
- 반응형 프로그래밍은 주변 환경과 끊임없이 상호 작용을 하는 프로그래밍을 의미합니다. 프로그램이 주도하는 것이 아니라 환경이 변하면 이벤트를 받아 프로그램이 동작하도록 만드는 프로그래밍 기법.
기존의 명령형 프로그래밍에서는 a=b+c 에서 a는 b+c의 연산이 끝난 이후에 그 결과를 통해 값이 할당됩니다. 만약 이후에 b나 c의 값이 변하더라도 a에는 영향을 주지 않기 때문에 문제가 생길 수 있습니다. 반면 리액티브 프로그래밍에서는 b나 c의 값이 변동되더라도 b+c 연산을 다시 할 필요 없이 자동으로 업데이트됩니다.
Rx는 반응형 프로그래밍이라면 뒤에 같이 붙어서 사용되는 RxJava, RxKotlin, RxAndroid란 무엇일까?
2. RxJava, RxAndroid 란?
- RxJava : ReactiveX(Reactive Extensions)를 Java로 구현한 라이브러리.
- RxAndroid : RxJava에 안드로이드용 스케쥴러 등 몇 가지 클래스를 추가해 안드로이드에서 비동기 개발을 쉽게 해주는 라이브러리다.
RxKotlin, RxJava, RxAndroid, RxSwift 등등 다양한 용어가 있기는 하지만 서로 다르기 보다는 어떤 언어나 플랫폼을 갖고 반응형 프로그래밍을 구현할 것이냐 를 의미한다고 보면 될 것같다. RxJava를 기반으로 Android나 Kotlin에서 편하게 사용하기 위해 클래스가 추가 되는 등의 부가적인 요소가 있다.
3. RxJava의 장단점
장점 :
- 비동기 프로그래밍 간소화 : 복잡한 비동기 작업을 더 쉽게 관리할 수 있도록 도와준다. 간단한 코드로 효율적인 비동기 처리가 가능. 예를 들면 콜백(Callback)에서 또 콜백을 할 때 좀더 쉽고 유연하게 처리 가능.
- 높은 가독성 : 프로그래밍의 간소화로 코드의 가독성이 높아진다.
- 쉬운 데이터 흐름 조작 : 여러가지 연산자를 사용해서 좀더 데이터를 쉽게 조작 할 수 있다.
- 스레드 관리의 유연성: Scheduler의 사용으로 어떤 스레드에 어떤 작업을 수행할지 쉽게 지정할 수 있다.
단점 :
- 러닝커브가 가파르다 : 배우기도 어렵고 함수형 프로그래밍에 지식이 없으면 배우기 더 어렵다.
- 실무 적용이 어렵다 : 배우더라도 어떤 방식으로 활용되는지 익숙하지 않다면 적용이 어렵다.
4. RxJava 구성요소
주요 구성요소는 Observable(관찰자), Observer(구독자), Operator (연산자), Scheduler(스케줄러)가 될 거 같습니다.
- Observable (관찰자): Observable은 데이터 스트림이다. 하나의 스레드에서 다른 스레드로 전달 할 데이터를 압축한다.
- Observer (구독자) : 생성된 이벤트 스트림을 구독하는 객체로, 새로운 이벤트를 수신할 때마다 처리하는 로직을 구현
- Operator (연산자) : Observable(관찰자)에서 생성된 이벤트 스트림을 변환, 조작하거나 여러 스트림을 결합하는 역할을 합니다. (맵핑, 필터링, 병합 등의 작업을 수행)
- Scheduler (스케줄러) : 이벤트 스트림이 어떻게 동작할지 제어하는 도구입니다. 동시성, 병렬성, 스레드 관리 등을 담당합니다.
5. 간단한 사용 예제
a) Hello, World 예제
val observer = object : Observer<String> { override fun onSubscribe(d: Disposable) {} override fun onNext(t: String) { _rxLiveData1.value = t } override fun onError(e: Throwable) {} override fun onComplete() {} } val observable = Observable.create { emitter -> emitter.onNext("Hello, World") } observable .subscribeOn(Schedulers.computation()) // Observable의 연산을 계산 스레드에서 실행 .observeOn(AndroidSchedulers.mainThread()) // Observer의 콜백을 IO 스레드에서 실행 .subscribe(observer)
Observer
- onSubscribe: Observable이 Observer와 구독을 설정할 때 호출됩니다.
- onNext: 데이터 발행 시 호출되며, 여기서 _rxLiveData1.value에 데이터를 할당하고 있습니다.
- onError: Observable에서 에러가 발생하면 호출됩니다.
- onComplete: Observable의 데이터 발행이 완료되면 호출됩니다.
Observable
- create: Observable을 새로 생성하며, 생성된 Observable은 emitter를 통해 Observer에 데이터를 전달할 수 있습니다.
- emitter.onNext: Observable이 데이터를 발행하고 Observer의 onNext 메서드를 호출합니다. 이 예제에서는 "Hello, World" 문자열을 Observer에 발행하고 있습니다.
Scheduler 및 Subscribe
observable .subscribeOn(Schedulers.computation()) .observeOn(Schedulers.io()) .subscribe(observer)
- subscribeOn : Observable에서 아이템을 발행할 스레드에서 결정한다
- observeOn : Observable이 발행한 데이터를 관찰할 스레드를 결정한다.
b) 5초 Count 예제
Observable까지 만들기 귀찮다면 한꺼번에 넣을 수도 있다.
Observable.create { emitter -> for (num in 0..5) { emitter.onNext("num : $num") Thread.sleep(1000) // 1초 지연 } emitter.onComplete() }.subscribeOn(Schedulers.io()) // Observable의 연산을 계산 스레드에서 실행 .observeOn(AndroidSchedulers.mainThread()) // Observer의 콜백을 IO 스레드에서 실행 .subscribe({ _rxLiveData2.value = it // onNext }, { _rxLiveData2.value = it.toString() // onError }, { _rxLiveData2.value = "Complete Counting from 0 to 5" // onComplete })
위에 예제와는 다르게 for loop를 사용해서 6번 데이터를 emitter.onNext()로 발행하고
발행을 다하면 emitter.onComplete로 종료하는 코드다.
subscribe에 차례대로 onNext, onError, onComplete block이 들어가있다.
onError와 onComplete는 생략할 수 있다.
간단한 학습 후 느낀점 :
RxJava가 편리할 것 같으면서도 어려운 것 같은 느낌이 드는 것은 내부적으로 사용할 수 있는 요소들이 너무 많다는 것이다.
RxJava에서 사용할 수 있는 Class만 해도 5가지 종류이다 그리고 활용할 수 있는 Operator들도 굉장히 많다.
Class와 Operator 조합을 하면 정말 다양하게 사용해볼 수 있지만 숙련되어 있지 않다면 활용하기 어려울거라는 느낌이 든다.
그래서 class 종류나 중요한 Operator들만 먼저 학습을 진행하고 그 외의 상황에서 필요한 것은 필요할 때 학습 하는 방향으로 진행되어야 할 것 같다. 다음편에서는 다양한 RxJava에서 사용할 수 있는 클래스를 알아보자.
'안드로이드 학습 > Android 기술면접 대비' 카테고리의 다른 글
Handler와 Looper (0) 2024.08.20 Serializable, Parcelable (Intent) 그리고 Parcelize (0) 2024.08.08 안드로이드 비동기 처리 1 (Thread, Runnable, Executor Service) (0) 2024.07.18 안드로이드 LiveData (0) 2024.02.06 안드로이드 프로세스 및 어플리케이션 생명주기 (0) 2024.01.18