[안드로이드 Jetpack Compose Paging3 시리즈] RemoteMediator 적용하기 #11

2024. 2. 29. 11:30·안드로이드/Compose Paging3
반응형

1. RemoteMediator를 Pager에 적용하기

안녕하세요. 지난 포스팅에서는 안드로이드 Jetpack Compose의 Paging3 라이브러리에서 제공하는 RemoteMediator를 구현하고, 코드를 분석하면서 어떤 역할을 하는지에 대해 살펴보았습니다. 이번 포스팅은 RemoteMediator와 PageSource를 Pager에 전달해서 화면에 정상적으로 UI가 보이는지 확인하겠습니다.

캐시 데이터로 영화목록을 불러온 모습
비행기 모드(데이터 사용 X)를 키고 앱을 실행시켰을 때, 캐시 데이터를 사용해서 영화 목록을 보여주는 모습

2. 안드로이드 Jetpack Compose Pager 구현 과정

Pager의 매개변수에 RemoteMediator와 PagingSource를 전달해주어야 합니다. Hilt 라이브러리를 이용해서 의존성을 주입받고, Pager 객체에 적절한 매개변수를 전달해서 RemoteMediator 기능이 적용된 Pager를 반환하는 함수를 MovieRepository 내부에 구현하겠습니다.

2-1. RemoteMediator 의존성 주입하기

MovieRepository에서 MovieRemoteMedaitor를 사용하기 위해서 의존성을 주입하겠습니다. RemoteMediator에서는 네트워크 통신과 로컬 데이터베이스를 모두 해야 하기 때문에 RemoteDataSource와 LocalDataSource를 모두 주입받는 모습입니다.

// DataModule.kt

@Provides
@Singleton
fun provideMovieRepository(
    movieRemote: MovieDataSource.Remote,
    movieLocal: MovieDataSource.Local,
    movieRemoteMediator: MovieRemoteMediator
): MovieRepository {
    return MovieRepositoryImpl(
        remote = movieRemote,
        local = movieLocal,
        remoteMediator = movieRemoteMediator
    )
}

@Provides
@Singleton
fun provideMovieMediator(
    movieLocalDataSource: MovieDataSource.Local,
    movieRemoteDataSource: MovieDataSource.Remote
): MovieRemoteMediator {
    return MovieRemoteMediator(movieLocalDataSource, movieRemoteDataSource)
}

2-2. MovieRepository에서 Paging 데이터 스트림 반환하기

네트워크 통신으로만 영화 목록을 가져오는 movies 함수 및 로컬 데이터베이스와 네트워크 통신 모두 사용하는 moviesUsingRemoteMediator 함수의 모습입니다. PagingSource를 제공하는 부분과 RemoteMediator의 존재에서 차이가 생깁니다.

// MovieRepositoryImpl.kt (Data Layer)

class MovieRepositoryImpl(
    private val remote: MovieDataSource.Remote,
    private val local: MovieDataSource.Local,
    private val remoteMediator: MovieRemoteMediator
) : MovieRepository {
    /**
     * 네트워크 통신만을 사용하여 영화 목록 가져오기
     */
    override fun movies(pageSize: Int): Flow<PagingData<MovieEntity>> {
        return Pager(
            config = PagingConfig(
                pageSize = pageSize,
                enablePlaceholders = false,
            ),
            pagingSourceFactory = { MoviesPagingSource(remote) }
        ).flow
    }

    /**
     * 로컬 데이터베이스와 네트워크 통신을 사용하여 영화 목록 가져오기
     */
    @OptIn(ExperimentalPagingApi::class)
    override fun moviesUsingRemoteMediator(pageSize: Int): Flow<PagingData<MovieEntity>> {
        return Pager(
            config = PagingConfig(
                pageSize = pageSize,
                enablePlaceholders = false,
            ),
            pagingSourceFactory = { local.pagingSource() },
            remoteMediator = remoteMediator
        ).flow.map { pagingData ->
            pagingData.map { it.toDomain() }
        }
    }
}

2-3. Domain Layer에서 moviesUsingRemoteMediator를 호출하도록 변경

기존에는 Domain Layer에서 movies함수를 호출하고 있었습니다. RemoteMediator를 적용한 moviesUsingRemoteMediator를 호출하도록 변경하면 됩니다.

UI Layer에서는 별도의 수정 없이 정상적으로 작동하는 모습을 확인할 수 있습니다.
이렇게 클린 아키텍처의 장점도 확인할 수 있습니다.

// Getmovies.kt (Domain Layer)
class GetMovies (
    private val movieRepository: MovieRepository
){
//    operator fun invoke(pageSize: Int): Flow<PagingData<MovieEntity>> = movieRepository.movies(pageSize)
    operator fun invoke(pageSize: Int): Flow<PagingData<MovieEntity>> = movieRepository.moviesUsingRemoteMediator(pageSize)
}

3. 안드로이드 Jetpack Compose Paging3 시리즈를 마치며

이번 시리즈를 통해 안드로이드 Jetpack Compose의 Paging3 라이브러리 사용 방법과 RemoteMediator를 통한 효율적인 데이터 관리 방법을 알아보았습니다. 

RemoteMediator를 적용하면 네트워크 데이터와 로컬 데이터베이스를 결합하여 사용자에게 더 빠른 데이터 로드 및 좋은 UX를 제공할 수 있습니다.

그러나 RemoteMediator의 구현이 필수는 아니기 때문에 진행하는 프로젝트의 성격에 맞춰서 판단하면 좋을 것 같습니다.

저작자표시 비영리 변경금지 (새창열림)

'안드로이드 > Compose Paging3' 카테고리의 다른 글

[안드로이드 Jetpack Compose Paging3 시리즈] RemoteMediator 코드 설명 #10  (0) 2024.02.28
[안드로이드 Jetpack Compose Paging3 시리즈] RemoteMediator 구현하기 #9  (0) 2024.02.27
[안드로이드 Jetpack Compose Paging3 시리즈] Local Data Source 생성하기 #8  (0) 2024.02.26
[안드로이드 Jetpack Compose Paging3 시리즈] Room Database 세팅하기 #7  (0) 2024.02.25
[안드로이드 Jetpack Compose Paging3 시리즈] RemoteMediator 파헤치기 #6  (0) 2024.02.24
'안드로이드/Compose Paging3' 카테고리의 다른 글
  • [안드로이드 Jetpack Compose Paging3 시리즈] RemoteMediator 코드 설명 #10
  • [안드로이드 Jetpack Compose Paging3 시리즈] RemoteMediator 구현하기 #9
  • [안드로이드 Jetpack Compose Paging3 시리즈] Local Data Source 생성하기 #8
  • [안드로이드 Jetpack Compose Paging3 시리즈] Room Database 세팅하기 #7
코딩덕
코딩덕
안드로이드, 리액트 등의 개발 노하우와 최신 AI 기술을 다루는 기술 블로그입니다. 실무 중심의 경험을 바탕으로 마주한 문제와 해결 과정을 체계적으로 기록하며, 개발자에게 실질적으로 도움 되는 프로그래밍 팁과 인사이트를 쉽고 명확하게 공유하고자 합니다.
  • 코딩덕
    개발자가 들려주는 IT 이야기
    코딩덕
  • 전체
    오늘
    어제
    • 분류 전체보기 (66)
      • 안드로이드 (62)
        • 멀티 모듈 (11)
        • 클린 아키텍처 (11)
        • 트러블 슈팅 (5)
        • 코틀린 (3)
        • 코루틴 (2)
        • Compose (1)
        • Compose UI (6)
        • Compose Dialog (8)
        • Compose Paging3 (11)
        • Compose State (2)
        • Util (1)
      • Github (3)
        • PR Template (2)
        • AI Code Review (1)
      • 리액트 (1)
        • NextJs (1)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Usecase
    멀티 모듈
    sealed class
    코틀린
    jsonadapter
    LazyRow
    안드로이드
    pr template
    코루틴
    ViewModel
    pager
    ai code review
    flow
    paging3
    Clean Architecture
    클린 아키텍처
    데이터 레이어
    recyclerview
    트러블슈팅
    multi module
    UI Layer
    Gradle
    enum class
    OnBackPressedDispatcher
    Dialog
    ScrollView
    dynamic json
    Github
    MutableState
    Jetpack Compose
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩덕
[안드로이드 Jetpack Compose Paging3 시리즈] RemoteMediator 적용하기 #11
상단으로

티스토리툴바