RemoteMediator PREPEND is getting called multiple times when not needed
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 25/100
Hướng nghiên cứu
Bắt đầu với PagingWithNetworkSample đã được sửa đổi và kiểm tra PageKeyedRemoteMediator.load, cấu hình Pager trong postsOfSubreddit và RedditPostDao.postsBySubreddit. Tái hiện chuỗi REFRESH, PREPEND và APPEND với các phiên bản Paging, Room và Kotlin đã nêu, sau đó theo dõi lý do các lần tải ở ranh giới bị lặp lại và xác định số lượng request dự kiến trước khi thay đổi hành vi.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
I'm facing an issue with paging library requesting 'too much' data when requesting the information from the middle of the 'data source':
For my scenario I can request both previous and next pages (Remote mediator load types PREPEND and APPEND). After initial portion (Remote mediator loadType REFRESH) and one APPEND and one PREPEND (as far as I can see from the source code paging lib will always request one page before and one page after after initial REFRESH) the library call mediator's load with 'PREPEND' loadType 1-3 more times, doesn't matter how big my page (and initial load) is, 30 or 300 elements. So my network calls sequence looks like
---> REFRESH
---> PREPEND
---> APPEND
---> PREPEND
---> PREPEND
When I'm scrolling and reaching boundary conditions, paging lib often requests 2-3 pages, instead of 1.
This all happens only when both PREVIOUS and NEXT pages are available. If user can scroll one direction only, most of the time, only 1 page is requested when user hits boundary condition.
Is it possible to control how many pages does paging library request (in order to reduce payload on the backend)
For the testing purposes, I modified this sample app to get 'endless stream of network data': https://github.com/android/architecture-components-samples/tree/master/PagingWithNetworkSample
@OptIn(ExperimentalPagingApi::class)
class PageKeyedRemoteMediator(
private val db: RedditDb,
private val redditApi: RedditApi,
private val subredditName: String
) : RemoteMediator<Int, RedditPost>() {
private val postDao: RedditPostDao = db.posts()
private val remoteKeyDao: SubredditRemoteKeyDao = db.remoteKeys()
var minIndex = 0
var maxIndex = 0
override suspend fun initialize(): InitializeAction {
// Require that remote REFRESH is launched on initial load and succeeds before launching
// remote PREPEND / APPEND.
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, RedditPost>
): MediatorResult {
try {
delay(1000)
val size = if (loadType == REFRESH) state.config.initialLoadSize else state.config.pageSize
println(">>>>> $loadType: ${if (loadType == APPEND) minIndex else maxIndex}")
val items = (0 until size).map {
val value = if (loadType == APPEND) minIndex-- else maxIndex++
RedditPost(
name = value.toString(),
title = value.toString(),
score = value,
author = value.toString(),
subreddit = subredditName,
num_comments = value,
created = System.currentTimeMillis(),
thumbnail = null,
url = null
).apply {
indexInResponse = value
}
}
db.withTransaction {
if (loadType == REFRESH) {
postDao.deleteBySubreddit(subredditName)
}
postDao.insertAll(items)
}
return MediatorResult.Success(endOfPaginationReached = items.isEmpty())
} catch (e: IOException) {
return MediatorResult.Error(e)
} catch (e: HttpException) {
return MediatorResult.Error(e)
}
}
}
@Dao
interface RedditPostDao {
...
@Query("SELECT * FROM posts WHERE subreddit = :subreddit ORDER BY num_comments DESC")
fun postsBySubreddit(subreddit: String): PagingSource<Int, RedditPost>
...
}
...
override fun postsOfSubreddit(subReddit: String, pageSize: Int) = Pager(
config = PagingConfig(pageSize),
remoteMediator = PageKeyedRemoteMediator(db, redditApi, subReddit)
) {
db.posts().postsBySubreddit(subReddit)
}.flow
...
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
val posts = flowOf(
clearListCh.receiveAsFlow().map { PagingData.empty<RedditPost>() },
savedStateHandle.getLiveData<String>(KEY_SUBREDDIT)
.asFlow()
.flatMapLatest { repository.postsOfSubreddit(it, 100) }
// cachedIn() shares the paging state across multiple consumers of posts,
// e.g. different generations of UI across rotation config change
.cachedIn(viewModelScope)
).flattenMerge(2)
...
lifecycleScope.launchWhenCreated {
model.posts.collectLatest {
adapter.submitData(it)
}
}
Paging infra setup:
- Local db + Network (RemoteMediator)
- Room at persistence layer
- Coroutines
- Libs versions:
- paging = "3.1.0-rc01"
- room = "2.4.0-beta01"
- kotlin = "1.4.21"
- recyclerview = "1.2.1"
- Ngôn ngữ chính
- Kotlin
- Star
- 509
- Fork
- 268
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của android/codelab-android-paging
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 62/100
android/codelab-android-paging#236 · 3 reaction ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 38/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 35/100
android/codelab-android-paging#243 · 1 bình luận · 1 reaction ·
-
Độ khó 2/5 1-2 ngày Mức phù hợp với người mới 35/100
android/codelab-android-paging#241 · 1 bình luận ·
Tất cả issue của android/codelab-android-paging
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
-
Voratoon change link broĐang mởSource is down
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
keiyoushi/extensions-source#19491 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100