Intermediaries(선택적) : 스트림이나 스트림 자체에서 출력된 각각의 값을 수정할 수 있습니다.
Consumer : 스트림으로부터 전달된 값을 소비합니다.
코드 작성해보기
1. Flow 생성
class NewsRemoteDataSource(
private val newsApi: NewsApi,
private val refreshIntervalMs: Long = 5000
) {
val latestNews: Flow<List<ArticleHeadline>> = flow {
while(true) {
val latestNews = newsApi.fetchLatestNews()
emit(latestNews) // Flow로 요청된 결과를 출력
delay(refreshIntervalMs) // 일정시간 중지
}
}
}
// suspend function 을가지고 네트워크 요청을 제공하는 인터페이스
interface NewsApi {
suspend fun fetchLatestNews(): List<ArticleHeadline>
}
flow 빌더 함수 내 emit 함수를 사용하여 값을 데이터 스트림에 출력할 수 있는 Flow를 만듭니다.
Producer가 coroutine에 존재하여, suspend function이 리턴될 때 까지 정지상태로 유지됩니다. * coroutine은 아래의 포스팅 참고
Producer가 다른 CoroutineContext의 값을 emit할 수 없습니다. 이런 경우 callbackFlow 같은 다른 Flow 빌더를 사용할 수 있습니다.
2. 스트림 수정
Intermediaries 값을 소비하지 않고 중간 연산를 활용하여 스트림을 수정할 수 있습니다.
class NewsRepository(
private val newsRemoteDataSource: NewsRemoteDataSource,
private val userData: UserData
) {
/**
* Flow을 변환 시켜 좋아하는 최신 뉴스를 출력 (lazy하고 Flow를 trigger 하지 않음)
* 해당 시점에 Flow에서 출력된 값입니다.
*/
val favoriteLatestNews: Flow<List<ArticleHeadline>> =
newsRemoteDataSource.latestNews
// 즐겨찾는 주제 목록을 필터링하는 중간 연산 작업
.map { news -> news.filter { userData.isFavoriteTopic(it) } }
// 최신 뉴스를 캐시에 저장하는 중간 연산 작업
.onEach { news -> saveInCache(news) }
}
위의 코드는 중간 연산으로 map을 사용하여 좋아하는 최신 뉴스의 목록을 반환합니다.
중간 연산이 많아질 수록 느려질 수 있습니다.
3. Flow로부터 수집
터미널 연산자를 사용하여 Flow를 트리거 후 값 수신을 시작합니다. * 터미널 연산자 : 일시 중단 함수(collect , single , reduce , toList 등)이거나 지정한 스코프에서 flow를 수집을 시작(launchIn)하는 연산자
Flow를 출력하여 스트림에 모든 값을 얻기 위해 collect를 사용합니다.
collect
suspend function이고 coroutine 안에서 실행해야 합니다.
모든 새 값에서 호출되는 매개변수로 람다를 사용합니다.
일시 중단 기능이므로, collect를 호출하는 coroutine은 Flow가 끝날 때 까지 정지합니다.
class LatestNewsViewModel(
private val newsRepository: NewsRepository
) : ViewModel() {
init {
viewModelScope.launch {
// Flow를 트리거하고 collect를 사용하여 element를 소비합니다.
newsRepository.favoriteLatestNews.collect { favoriteNews ->
// 최신 인기뉴스 보기 업데이트 코드
}
}
}
}
collect은 최신 뉴스를 새로고침하는 생산자를 트리거합니다.
또한, 고정된 간격으로 네트워크 요청의 결과를 출력합니다.
1. Flow 생성 에서 producer가 while(true) 인 상태이므로, ViewModel이 초기화되고, viewModelScope가 취소된다면, 데이터의 스트림은 닫힙니다.
Flow collection의 중지 조건
collect 하는 coroutine이 취소되면, producer도 같이 멈추게 됩니다.
producer가 출력을 종료하였을 때, 데이터 스트림이 닫히고, collect를 호출한 coroutine이 재 실행합니다.
Flow는
다른 중간 연산자가 없으면, cold 하고 lazy 하다
producer는 터미널 연산자가 Flow에서 호출될 때 마다 producer 코드가 실행된다는 의미
[TIL-230626] Android Flow 알아보기 - 1
안녕하세요
6월 말이 되면서 계속 더워지고 있고, 지쳐서 공부에 소홀해지기 쉬운데,
하루에 단 30분이라도 꾸준히 작성하자는 마인드가 필요해보입니다
오늘은 Android Flow에 관해서, 포스팅을 작성해보려 합니다.
(아래는 Flow와 관련은 없지만 이미지를 넣고싶어서 넣어봤습니다)
Flow의 주요한 개념은
1. Flow 생성
* coroutine은 아래의 포스팅 참고
[TIL-230625] Android Coroutine 알아보기
안녕하세요 오늘은 Kotlin의 Coroutine에 대해서 간략하게 포스팅 해보겠습니다. Coroutine 이란? 비동기로 실행되는 코드를 단순화하기 위해 Android에서 사용할 수 있는 동시성 디자인 패턴 메인 스레
weirddev.tistory.com
2. 스트림 수정
3. Flow로부터 수집
* 터미널 연산자 : 일시 중단 함수(collect , single , reduce , toList 등)이거나 지정한 스코프에서 flow를 수집을 시작(launchIn)하는 연산자
** 남은 내용은 다음 포스팅에서 이어집니다.
이번에는 Kotlin Flow에 대해 알아보았습니다
잘못된 내용이 있다면 댓글 부탁드리고, 내용이 좋았다면 공감, 구독 부탁드려요!
'DEV > Android' 카테고리의 다른 글