일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ㅓ
- Kotlin
- Observer Pattern
- 빌터패턴
- 디자인패턴 #
- Functional Programming
- a
- 코틀린
- builderPattern
- 디자인패턴
- Abstract Factory
- designPattern
- 팩토리 메소드
- 싱글톤
- Singleton
- factory method
- ㅋㅁ
- El
- 프로토타입 패턴
- Design Pattern
- F
- 함수형프로그래밍
- 추상팩토리패턴
- PrototypePattern
- 추상 팩토리
- 옵저버 패턴
- r
- Today
- Total
오늘도 더 나은 코드를 작성하였습니까?
RemoteMediator 구현하기 본문
RemoteMediator의 기본 구현
Pager가 데이터를 모두 사용했거나 기존 데이터가 무효화되었을 때 네트워크에서 더 많은 데이터를 로드하는 것입니다. RemoteMediator는 로드 동작을 정의하기 위해 재정의해야 하는 load() 메서드를 포함합니다.
일반적인 RemoteMediator 구현에는 다음 매개변수가 포함됩니다.
- query 백엔드에서 검색할 데이터를 정의하는 쿼리 문자열
- database: 로컬 캐시의 역할을 하는 데이터베이스
- networkService: 백엔드 서비스 API 요청
RemoteMediator<Key, Value> 구현을 만듭니다.
Key 유형과 Value 유형은 동일한 네트워크 데이터 소스의 PagingSource를 정의하는 경우와 동일하다.
@OptIn(ExperimentalPagingApi::class)
class ExampleRemoteMediator(
private val query: String,
private val database: RoomDb,
private val networkService: ExampleBackendService
) : RemoteMediator<Int, User>() {
val userDao = database.userDao()
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, User>
): MediatorResult {
// ...
}
}
load() 메서드는 데이터 세트를 업데이트하고 기존 PagingSource를 무효화합니다
페이징을 지원하는 일부 라이브러리(예: Room)는 구현하는 PagingSource 객체의 무효화를 자동으로 처리합니다.
load() 메서드는 다음과 같은 두 매개변수를 사용합니다.
매개변수
PagingState: 지금까지 로드한 페이지, 가장 최근에 액세스한 색인, 페이징 스트림을 초기화하는 데 사용한 PagingConfig 객체에 관한 정보를 포함합니다.
LoadType: 로드의 유형을 REFRESH, APPEND, PREPEND 중 하나로 나타냅니다.
이전에 로드한 데이터의 끝 부분(LoadType.APPEND) / 시작 부분(LoadType.PREPEND) / 데이터를 처음으로 로드하는지(LoadType.REFRESH)
반환값
MediatorResult : MediatorResult.Error(오류 설명 포함) 또는 MediatorResult.Success(로드할 데이터가 더 있는지 여부를 나타내는 신호 포함)일 수 있습니다.
load()의 기본 로직.
- 로드 유형(LoadType)및 지금까지 로드된 데이터에 따라 네트워크에서 로드할 페이지를 결정합니다
- 네트워크 요청을 트리거합니다
- 로드 작업 결과에 따라 작업을 실행합니다
성공적인 데이터 로드
- 로드한 데이터가 비어 있지 않으면 데이터베이스에 저장해줌
- MediatorResult.Success(endOfPaginationReached = false) 반환하여 아직 마지막 페이지가 아님을 알린다.
- 데이터가 저장된 후에는 PagingSource를 무효화하여 페이징 라이브러리에 새 데이터를 알립니다.
- 로드가 성공했지만 수신된 항목 비어 있거나 마지막 페이지인 경우 MediatorResult.Success(endOfPaginationReached = true)를 반환합니다. 이전 페이지가 마지막이였음을 알려줌.
- 데이터가 저장된 후에는 PagingSource를 무효화하여 페이징 라이브러리에 새 데이터를 알립니다.
오류가 발생한 경우
- MediatorResult.Error를 반환합니다.
초기화 메소드 initialze() 정의하기
initialize()
- 초기화 담당.
- 메서드를 재정의하여 캐시된 데이터가 오래되었는지 점검하고 원격 새로고침을 트리거할지 결정 하는 곳.
- 로드하기 전에 실행되므로 로컬 또는 원격 로드를 트리거하기 전에 데이터베이스를 조작할 수 있습니다(예: 기존 데이터 삭제)
- InitializeAction을 반환
initialize()는 비동기 함수이므로 데이터를 로드하여 데이터베이스에 있는 기존 데이터의 관련성을 확인할 수 있습니다.
가장 일반적인 사례는 캐시된 데이터가 특정 기간에만 유효한 경우입니다.
RemoteMediator는 만료 기간이 지났는지 확인할 수 있으며, 이런 경우 페이징 라이브러리는 데이터를 완전히 REFRESH해야 합니다.
override suspend fun initialize(): InitializeAction {
val cacheTimeout = TimeUnit.HOURS.convert(1, TimeUnit.MILLISECONDS)
return if (System.currentTimeMillis() - db.lastUpdated() >= cacheTimeout)
{
// Cached data is up-to-date, so there is no need to re-fetch
// from the network.
InitializeAction.SKIP_INITIAL_REFRESH
} else {
// Need to refresh cached data from network; returning
// LAUNCH_INITIAL_REFRESH here will also block RemoteMediator's
// APPEND and PREPEND from running until REFRESH succeeds.
InitializeAction.LAUNCH_INITIAL_REFRESH
}
}
Pager 생성
- PagingSource 생성자를 직접 전달하는 대신 DAO에서 PagingSource 객체를 반환하는 쿼리 메서드를 제공(pagingsourceFactory)
- RemoteMediator 객체를 remoteMediator 매개변수로 제공
@OptIn(androidx.paging.ExperimentalPagingApi::class)
fun getSearchResultStream(query: String): Flow<PagingData<Repo>> {
val dbQuery = "%${query.replace(' ', '%')}%"
val pagingSourceFactory = { database.reposDao().reposByName(dbQuery) }
return Pager(
config = PagingConfig(
pageSize = NETWORK_PAGE_SIZE,
enablePlaceholders = false
),
remoteMediator = GithubRemoteMediator(
query,
service,
database
),
pagingSourceFactory = pagingSourceFactory
).flow
}
'Android Jetpack Architecture > Paging3' 카테고리의 다른 글
REFRESH 배치 (0) | 2021.08.23 |
---|---|
paging3 race conditions 처리와 remote keys 관리하기 (0) | 2021.08.19 |
네트워크 및 데이터베이스의 페이징. (0) | 2021.08.19 |
UI에 페이징된 데이터 표시 (0) | 2021.08.19 |
PagingDataAdapter 정의하기. (0) | 2021.08.19 |