- RxAndroid로 리액티브 앱 만들기 #1
- RxAndroid로 리액티브 앱 만들기 #2
- RxAndroid로 리액티브 앱 만들기 #3
- RxAndroid로 리액티브 앱 만들기 #4
출처 : https://realm.io/kr/news/rxandroid2/
이 시리즈는 마이크로소프트웨어에 기고된 내용이 일부 수정되어 포함되어 있습니다.
이번에는 지난 시간에 이어 데이터를 어떻게 다루는지 Map을 비롯한 오퍼레이터를 통해 살펴보겠습니다. 또 복잡한 콜백 클래스와 메서드를 람다를 통해 어떻게 코드를 단순화 시키는지를 다루겠습니다.
데이터 가공 Map
map은 한 데이터를 다른 데이터로 바꾸는 오퍼레이터입니다. 원본의 데이터는 변경하지 않고 새로운 스트림을 만들어 냅니다. 스트림의 데이터를 각각 10 씩 곱을 하는 예를 볼 수 있습니다.
이렇게 map 사용하려면 인자 하나를 받아 값을 10배를 곱해 반환하는 메서드를 map 전달해야 합니다.
.map(new Func1<Integer, Integer>() { @Override public Integer call(Integer value) { return value * 10; } })
RxAndroid를 사용하여 앱을 개발할 때 미리 준비된 다양한 RxJava 오퍼레이터를 사용할 수 있습니다. 오퍼레이터는 기존에 작성된 메서드를 재사용하여 전체 값을 변경할 수 있는 도구입니다. 값을 재사용 가능한 함수를 이용해서 가공한다는 부분에서 함수형 프로그래밍과 일맥상통하는 부분이 있습니다.
문자열을 대문자로 바꾸는 것도 쉽게 구현할 수 있습니다.
simpleObservable .map(new Func1<String, String>() { @Override public String call(String text) { return text.toUpperCase(); } }) .subscribe(new Action1<String>() { @Override public void call(String text) { ((TextView) findViewById(R.id.textView)).setText(text); } });
옵저버블의 스트림을 대문자로 변환하는 (사실은 새로운 스트림을 만드는) map 호출하고 그것을 서브스크라이버에 연결하는 것을 보여줍니다.
map 이용할 때는 같은 타입으로만 변경해야 할 수 있는 것은 아닙니다. 다른 타입으로도 바꿀 수 있습니다.
simpleObservable .map(new Func1<String, Integer>() { @Override public Integer call(String text) { return text.length(); } }) .subscribe(new Action1<Integer>() { @Override public void call(Integer length) { ((TextView) findViewById(R.id.textView)).setText("length: " + length); } });
단일 데이터, 컬렉션을 옵저버블 생성을 위한 유틸리티
simpleObservable
은 문자열 하나만 전달하는 간단한 옵저버블인데 이런 경우 항상 새로 옵저버블을 만들 필요는 없습니다. 옵저버블을 쉽게 만들 수 있게 도와주는 유틸리티 메서드가 있습니다.Observable<String> simpleObservable = Observable.just("Hello RxAndroid");
연속적인 데이터를 처리하기 위한 유틸리티
Observable.from
도 있습니다. 이 유틸리티를 이용하면 배열이나 컬렉션을 보다 간편하게 처리합니다.번잡한 문법을 람다로 간단히
기존의 자바 문법에서 RxAndroid (RxJava) 프로그래밍을 할 때 로직과 상관없는 요소들이 많이 발견됩니다. 어노테이션, 클래스 선언, 메서드 선언 등의 요소들이 코드에서 반복되지요. 어떤 부분들은 반복을 제거할 수 없지만 Rx를 사용하기 위해 반복적으로 생성되는 클래스와 메서드 선언은 람다를 통해 줄일 수 있습니다. 람다를 사용하면 코드가 간결해져 가독성이 높아집니다.
Observable<String> simpleObservable = Observable.just("Hello Lambda!!"); simpleObservable .map(text -> text.length()) .subscribe( length -> ((TextView) findViewById(R.id.textView)).setText("length: " + length));
자바 코드가 매우 간결해진 것을 볼 수 있습니다. 람다 문법이 생소한 독자를 위해 코드 단위로 비교하며 설명하겠습니다.
.map(new Func1<String, Integer>() { @Override public Integer call(String text) { return text.length(); } })
람다를 사용하기 전
map
코드입니다. 람다는 단일 메서드를 가지고 있는 경우만 적용할 수 있습니다. 여기에서 메서드 인자 부분 이전의 번잡한 내용을 지워봅시다..map((String text) -> { return text.length(); })
익명 객체 부분을 제거한 람다 map 코드입니다. 인자의 타입을 추론할 수 있다면 그 부분도 생략할 수 있습니다.
.map((text) -> { return text.length(); })
인자가 하나인 경우에는 괄호를 생략할 수 있습니다.
.map(text -> text.length())
람다 블록 내에 문장이 하나이고 리턴값을 가진다면 블록, 세미콜론, 리턴 키워드를 지울 수 있습니다.
람다의 단 한가지 단점은 자바 8이상에서만 쓸 수 있다는 점입니다. 안드로이드는 자바 8을 지원하지 못하며 람다를 쓰기 위해서는 이전 버전에서 람다를 쓸 수 있게 하는 포팅 라이브러리를 사용해야 합니다.
람다 포팅 중 안드로이드에 알맞는 라이브러리는 레트로람다(Retrolambda)입니다. 레트로람다 라이브러리는 속도 상의 약점이 없고 기술 선도 기업들이 2013년 부터 안드로이드에 테스트해서 어느정도 검증 받았다고 볼 수 있습니다.
레트로람다 라이브러리를 사용하기 위해서는 그래들 코드의 설정의 수정이 필요합니다.
buildscript { repositories { jcenter() } dependencies { classpath 'me.tatarka:gradle-retrolambda:3.3.0-beta3' } } apply plugin: 'com.android.application' apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "io.realm.simpleobservable" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' compile 'io.reactivex:rxandroid:1.1.0' }
상단에 레트로람다 관련 빌드스크립트가 추가된 것과
apply plugin: 'com.android.application'
뒤에apply plugin: 'me.tatarka.retrolambda'
가 추가된 것을 주목하세요.만약 자바 8과 옛 버전을 함께 쓰길 원한다면 Gradle Retrolambda Plugin 프로젝트를 참고하세요.
이번 글에서는 리액티브 프로그래밍의 가장 기초적인 오퍼레이터와 그 활용법을 배웠습니다. 그 개념을 바탕으로 데이터 스트림을 간단히 연결하고 변형을 할 수 있습니다.
다음 시간에는 다양한 옵저버블과 오퍼레이터 등을 합성하여 사용자 인터페이스와 상호작용하는 방법을 알아보며 사용자 인터페이스 코드를 구조화하는 것을 해보겠습니다.
'프로그래밍 > Android' 카테고리의 다른 글
RxAndroid로 리액티브 앱 만들기 #4 (1) | 2016.10.14 |
---|---|
RxAndroid로 리액티브 앱 만들기 #3 (0) | 2016.10.14 |
RxAndroid로 리액티브 앱 만들기 #1 (0) | 2016.10.12 |
1. RxJava 와 RxAndroid - RX(Reactive Extensions)의 소개 (0) | 2016.08.31 |
Butter Knife (Field and method binding for android views) (0) | 2016.08.25 |