ABOUT ME

-

  • Android) LiveData와 Coroutine Flow 비교해보기
    Android 2021. 2. 5. 15:16


    요즘에 코루틴의 flow를 사용해서 안드로이드 개발을 하고 있는데, LiveData와 함께 flow를 사용 시

    올바르게 사용하고 있는 건지에 대한 궁금증이 생겨서 적합한 방법에 대해 글을 써보려고 합니다.

     

    Introduction

    LiveData는 일반적으로 데이터 전송을 위한 용도로 사용됩니다.

    Flow 또한 고유한 방식으로 데이터를 전송하고 비동기 작업을 수행하는 기능이 있습니다.

    둘 다 한계와 장점이 존재합니다.


    What is LiveData?

    LiveData는 AAC에서 소개되었고, 대부분의 개발자들은 MVVM 패턴에서 LiveData를 사용하여 ViewModel에서 데이터를 communicate 또는 transfer 하여 메모리 누수를 줄임으로써 수명주기 인식을 보장하고 있습니다. 

     

    간단히 말해 LiveData는 관찰 가능한 data holder class입니다.

    LiveData는 Activity, Fragment 및 Services와 같은 다른 안드로이드 구성요소에서 관찰할 수 있는 데이터 집합을 보유할 수 있습니다.

     

    LiveData수명주기를 인식합니다. 데이터를 관찰하는 구성 요소가 파괴되거나 활성화되지 않으면 LiveData는 해당 observer에게 데이터 게시를 중지합니다. 이 점은 기존 안드로이드 개발의 많은 문제를 해결합니다. 

     

    LiveData의 장점을 정리해보자면:

    • 메모리 누수가 없다.
    • 중지된 components로 인한 충돌이 없다.
    • 수동으로 수명주기 처리해줄 필요가 없다.
    • Resource를 공유할 수 있다.

    What is Flow?

    코루틴 이전에 대부분의 개발자는 비동기 처리를 위해 RxJava를 사용했습니다. 이후에 코루틴의 Flow API가 출시되었고, flow는 순차적으로 실행되는 데이터 스트림을 비동기 적으로 처리할 수 있는 특징이 있어 Rxjava의 대안으로 떠올랐습니다.

    자세한 내용은  Asynchronous Flow 참조.


    Key Difference between LiveData & Flow

    LiveData는 수명주기 문제를 처리하기 위해 번거롭지 않게 데이터를 관찰하는 데 사용됩니다.

    Flow는 지속적인 데이터 통합에 사용되며 비동기 프로그래밍에도 단순화되었습니다.

     

    Room을 사용하는 경우 LiveData를 사용하여 데이터베이스에서 UI로 데이터를 전송하여 기존 문제를 해결 가능합니다.

    하지만, 데이터베이스에 향후 변경 사항이 있을 때 LiveData는 이 상황에서 무력해집니다.

     

    이러한 문제는 Flow를 사용하여 해결할 수 있습니다. Flow를 사용하여 Room은 추가 코드를 작성하지 않고도 데이터베이스와 UI 간에 앱 전체에서 원활한 데이터 통합의 새로운 가능성을 만들었습니다.

     

    한 가지의 예를 살펴보겠습니다. FlowLiveData와 마찬가지로 Room에서 반환 값으로 사용 가능합니다.

    또한, FlowLiveData처럼 데이터베이스를 observing 가능합니다.

    @Query("SELECT * FROM users")
    fun getAllUsersFlow(): Flow<List<User>>

    만약 thread가 바뀌었을 때? 혹은 backpressure 같은 경우는 어떨까요? LiveData는 무력해지지만, Flow로는 처리가 가능합니다.

    // Repository.kt
    fun getAllUsersFlow(): Flow<List<User>> =
        dao.getAllUsersFlow()
            // do some mapping
            .flowOn(Dispatchers.Default)
            .conflate()

    예를 들어 Repository에서 flow flowOn() operator를 사용하여 쉽게 thread를 변경할 수 있습니다. 그리고 backpressurecollectoremiiter보다 느린 경우 방출된 값을 건너뛰는 conflate()를 부름으로써 처리해줄 수 있습니다.


    FlowLiveData와 한 프로젝트에 공존할 수 있고 함께 사용 시에 이점이 있습니다.

    ViewModel에서 FlowLiveData로 변경하는 두 가지 방법이 있습니다.

    asLiveData()를 통해 변경하는 방법과 liveData 빌더를 사용하는 방법이 있습니다.

    val users: LiveData<List<User>> = repository.getAllUsersFlow().asLiveData()
    val users: LiveData<List<User>> = liveData {
        // some additional work
        repository.getAllUsersFlow()
    }

    이후 평소 LiveDataobserve 하는 방식으로 View에서 사용 가능합니다.


    LiveData Flow는 서로를 보완하는 역할을 합니다.

    LiveData는 구성 변경시에 안정성을 제공하고 최신 데이터를 View로 전달하는 역할을 합니다.

     

    FlowUseCase, RepositoryDataSources 레이어와 긴밀하게 작동하여 데이터를 수집 및 처리하여 서로다른 코루틴 범위에서 작업을 실행합니다.

     

    그래서 ViewModelView 사이의 상호작용은 LiveData가, 더 깊은 레이어와 스레딩과 같은 더 복잡한 처리는 Flow가 책임을 지는 역할을 하게 됩니다.

     


    Preference

    Flow & LiveData

    반응형

    댓글

Designed by Me.