LiveData와 Flow

김명진·2021년 1월 3일
0

안드로이드

목록 보기
7/25
post-custom-banner

💡 정의

안드로이드와 결합할 때는 플로우를 직접 써도 좋지만 liveData와 함께 사용하는 것이 좋다. liveData가 데이터 바인딩과 결합하기 좋아서 flow 결과물을 liveData로 변환하여 전달하는 것이 편하기 때문이다.

플로우를 liveData로 바꾸는 것은 매우 간단하다.

구글에서는 flow를 안드로이드에서 편리하게 이용할 수 있도록 확장 Flow.asLiveData()를 만들었다. 해당 확장을 사용하기 위해서는 의존성 추가가 필요하다.

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"

💡 예제:

liveData와 플로우를 이용한 예제이다. 사용한 API는 worldtimeapi.org 이고 이는 시간을 제공해주는 API다. https://worldtimeapi.org/api/timezone/Asia/Seoul을 호출해서 얻은 json 사용한다.

json에서 사용될 것은 datatime이기 때문에 1개의 필드가 들어간 Result 클래스를 만든다.

data class Result(val datetime: String)

API를 사용하기 위해서는 Retrofit 인터페이스를 만든다.

interface WorldTimeApi{
	@GET("timezone/Asia/Seoul")
	suspend fun getSeoulTime(): Result
}

이제 viewModel에서 WorldTimeApi와 Result를 사용한다.

class viewModel: ViewModel() {

	private val retorfit = Retorfit.Builder()
		.baseUrl("https://worldtimeapi.org/api/")
		.addConverterFactory(GsonConverterFactory.create())
		.build()

	private val worldTimeApi = retorfit.create(WorldTimeApi::class.java)

	val seoulTime = flow {
		while (true) {
			emit(worldTimeApi.getSeoulTime())
			delay(5000)
		}
	}.flowOn(Dispatchers.IO)
		.asLiveData()

seoulTimeLiveData를 flow 빌더로 통해 만들었다. 계속 반복하며 WorldTimeApi.getSeoulTime을 호출하여 Flow에 emit으로 전달하고 한번 전달한 후에는 delay로 약 5초를 쉰다. 그리고 flow를 asLiveData로 바로 라이브 데이터로 변환하여 뷰모델을 사용할 뷰에 제공한다.

라이브 데이터가 더 이상 필요가 없어지면 자동으로 flow의 수행도 중단된다.

레이아웃은 서울 시간을 출력할 수 있도록 TextView로 구성했다.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    
    <data>
        <variable
            name="viewModel"
            type="com.example.android.flowlivedata.ViewModel" />
    </data>
    
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
        <TextView
            android:id="@+id/seoulTime"
            android:text="@{viewModel.seoulTime.datetime}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>
        
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

뷰 모델을 가져올 수 있도록 설정하고 viewModel의 seoulTime 라이브 데이터에서 datetime 필드를 연동한다.

출처: 김용욱, 『코틀린/자바를 한눈에 안드로이드 앱 프로그래밍』, 예문사(2020)

profile
꿈꾸는 개발자
post-custom-banner

0개의 댓글