Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- hilt
- notification
- CustomView
- 안드로이드
- View
- recyclerview
- Navigation
- AppBarLayout
- ViewModel
- CollapsingToolbarLayout
- LiveData
- 알고리즘
- Android
- activity
- lifecycle
- Behavior
- HTTP
- CoordinatorLayout
- onMeasure
- room
- onLayout
- sqlite
- 알림
- Coroutine
- 백준
- BOJ
- kotlin
- Algorithm
- 코틀린
- DataBinding
Archives
- Today
- Total
개발일지
Android in A..Z - Flow 본문
Flow
Flow는 Coroutine에서 여러 값을 순차적으로 보내는 유형입니다. Jetpack에서도 많이 쓰이는 유형이고, Iterator와 비슷하며 map, filter등 람다 함수를 지원하면서 suspend 함수에서 쓰이기 때문에 비동기 처리에 효율적입니다.
Flow 구성
- Producer : Flow Builder에서 비동기적으로 데이터를 생산한다.
- Intermediary : Stream에서 보내는 데이터를 소비하지 않고 수정한다.
- Consumer : 값을 사용한다.
Producer
Flow Builder를 통해 만든다. flow, channelFlow등 다양한 함수가 존재한다. Builder를 통해 Data를 만들고 emit을 통해 Data를 전달한다. Consume하는 함수가 수행될 때마다 Flow Builder가 수행되고 emit되는 값을 소비한다.
val data = flow {
doLog("Flow Start")
repeat(3) {
delay(500L)
doLog("Emit : $it")
emit(it)
}
doLog("Flow End")
}
Intermediary
map, filter같은 람다 함수로 Flow에서 값을 수정할 수 있습니다.
viewModel.data.map {
it + 10
}.filter {
it > 0
}.onEach {
viewModel.doLog("Map -> onEach : $it")
}.collect {
viewModel.doLog("Map -> onEach -> Collect : $it")
}
Consumer
single, first, collect 등이 있다.
viewModel.data.collect {
viewModel.doLog("Collect $it")
}
viewModel.data.first {
viewModel.doLog("First $it")
true
// False면 다시 받아온다.
// NoSuchElement 발생 가능성 있음
}
viewModel.doLog("First End")
- first : 반환형이 true인 첫번째 값, first()를 통해 무조건 첫번재 값을 받을 수 있다. emit된 값이 없거나 true를 만족하는 값이 없으면 Exception 발생
- single : Flow에서 emit된 값이 한개일 때 반환, emit된 값이 여러개면 Exception 발생
- collect : emit될 때마다 수행
Exception Controll
만약 Flow Builder에서 Exception이 발생한 경우, Flow Builder는 즉시 종료된다. 그리고 catch블록이 있으면 실행되는데 Flow를 수정할 수 있다.
val exceptionData = flow {
doLog("Exception Flow Start")
repeat(10) {
delay(500L)
if (it > 3) {
throw Exception("Exception : $it")
}
emit(it)
}
}
viewModel.exceptionData.catch {
viewModel.doLog(it.message)
emit(10)
}.collect {
viewModel.doLog("Exception Collect : $it")
}
다른 CoroutineContext에서 실행하기
flowOn을 통해 Flow Builder의 CoroutineContext를 수정할 수 있다.
val flowOn = flow {
repeat(10) {
delay(500L)
doLog("Channel Flow Send : $it")
emit(it)
}
}.onEach {
log.value += "FlowOn In ViewModel : $it"
}.flowOn(Dispatchers.Main) // ↑ Dispatchers.Main 영향을 받음
정리
기존의 suspend 함수는 함수의 실행이 종료되야 값을 한번에 반환한다. 즉 List같은 형식으로 값을 반환할 경우 List를 만들고 한번에 값을 반환한다. 하지만 Flow는 값을 emit하고 collect하는 과정에서 하나씩 받아올 수 있는 장점이 있는 것 같다.
Git (예제 코드)
https://github.com/KangTaeJong98/Example/tree/main/Android/Flow
'Android (안드로이드)' 카테고리의 다른 글
Android In A..Z - Google API (Google Map) (0) | 2021.08.18 |
---|---|
Android in A..Z - WebView Bridge (0) | 2021.08.05 |
Android in A..Z - Context (0) | 2021.08.05 |
Android in A..Z - Constraint Layout (0) | 2021.08.04 |
Android in A..Z - OnTouchListener, GestureEvent (0) | 2021.07.18 |
Comments