У меня медленная загрузка при прокрутке из-за необходимости сделать несколько сетевых вызовов.
class RepoResultPagingSource(
private val repository: Repository,
private val query: String
) : PagingSource() {
override suspend fun load(params: LoadParams): LoadResult {
try {
val page = params.key ?: 1
// network call to get repositories
val repos = repository.getRepositories(query, page, PAGE_SIZE)
val results = repos.map { repo ->
// uses repo to get its top contributor
val contributor = repository.getTopContributor(repo.owner.username, repo.reponame)
Result(repo.owner.url, repo.reponame, contributor.username?: "")
}
return LoadResult.Page(
data = repoResults,
prevKey = if (page == 1) null else page-1,
nextKey = page + 1
)
} catch (e: Exception) {
return LoadResult.Error(e)
}
}
class Repository(private val api: RepositoryApi,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO) {
suspend fun getRepositories(query: String, page: Int, perPage: Int): List
{
return withContext(dispatcher) {
api.search(query, page, perPage).repositories
}
}
suspend fun getTopContributor(ownerName: String, repoName: String): Contributor {
return withContext(dispatcher) {
api.getContributors(ownerName, repoName, 1).first()
}
}
}
Я понял, что загрузка блокируется, потому что библиотека подкачки вызывает ее из runBlockin
@JvmStatic
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun create(
pagingSource: PagingSource,
initialPage: PagingSource.LoadResult.Page?,
coroutineScope: CoroutineScope,
notifyDispatcher: CoroutineDispatcher,
fetchDispatcher: CoroutineDispatcher,
boundaryCallback: BoundaryCallback?,
config: Config,
key: K?
): PagedList {
val resolvedInitialPage = when (initialPage) {
null -> {
// Compatibility codepath - perform the initial load immediately, since caller
// hasn't done it. We block in this case, but it's only used in the legacy path.
val params = PagingSource.LoadParams.Refresh(
key,
config.initialLoadSizeHint,
config.enablePlaceholders,
)
runBlocking {
val initialResult = pagingSource.load(params)
when (initialResult) {
is PagingSource.LoadResult.Page -> initialResult
is PagingSource.LoadResult.Error -> throw initialResult.throwable
is PagingSource.LoadResult.Invalid ->
throw IllegalStateException(
"Failed to create PagedList. The provided PagingSource " +
"returned LoadResult.Invalid, but a LoadResult.Page was " +
"expected. To use a PagingSource which supports " +
"invalidation, use a PagedList builder that accepts a " +
"factory method for PagingSource or DataSource.Factory, " +
"such as LivePagedList."
)
}
}
}
else -> initialPage
}
return ContiguousPagedList(
pagingSource,
coroutineScope,
notifyDispatcher,
fetchDispatcher,
boundaryCallback,
config,
resolvedInitialPage,
key
)
}
Поэтому я добавляю viewModelScope для запуска неблокирующей сопрограммы, например
override suspend fun load(params: LoadParams): LoadResult {
try {
return scope.async {
val page = params.key ?: 1
// network call to get repositories
val repos = repository.getRepositories(query, page, 10)
val results = repos.map { repo ->
// uses repo to get its top contributor
val contributor = repository.getTopContributor(repo.owner.username,
repo.reponame)
Result(repo.owner.url, repo.reponame, contributor.username?: "")
}
return@async LoadResult.Page(
data = repoResults,
prevKey = if (page == 1) null else page-1,
nextKey = page + 1
)
}.await() as LoadResult
} catch (e: Exception) {
return LoadResult.Error(e)
}
}
К сожалению, прокрутка остается медленной, поэтому я спрашиваю
1. Правда ли, что загрузка по умолчанию выполняется в блокирующем режиме, несмотря на переключатель getRepositories и getTopContributor в Dispatchers.IO, в соответствии с Почему «withContext» не переключает сопрограммы в «runBlocking»? это
2. Поскольку мне нужно сделать 1 сетевой запрос для получения репозиториев, и каждому из этих репозиториев нужно найти своего основного участника, я делаю запросы page_size+1. Я ищу советы по улучшению производительности прокрутки, поскольку каждая страница зависит от этих сетевых запросов. Мой пейджер выглядит
val pagingData: Flow = Pager(
config = PagingConfig(pageSize = PAGE_SIZE, prefetchDistance = 4 * PAGE_SIZE),
pagingSourceFactory = { RepoResultPagingSource(repo, QUERY, viewModelScope) }
).flow.cachedIn(viewModelScope)
Подробнее здесь: https://stackoverflow.com/questions/784 ... d-function
Медленная прокрутка в функции загрузки paging3 ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1714932926
Anonymous
У меня медленная загрузка при прокрутке из-за необходимости сделать несколько сетевых вызовов.
class RepoResultPagingSource(
private val repository: Repository,
private val query: String
) : PagingSource() {
override suspend fun load(params: LoadParams): LoadResult {
try {
val page = params.key ?: 1
// network call to get repositories
val repos = repository.getRepositories(query, page, PAGE_SIZE)
val results = repos.map { repo ->
// uses repo to get its top contributor
val contributor = repository.getTopContributor(repo.owner.username, repo.reponame)
Result(repo.owner.url, repo.reponame, contributor.username?: "")
}
return LoadResult.Page(
data = repoResults,
prevKey = if (page == 1) null else page-1,
nextKey = page + 1
)
} catch (e: Exception) {
return LoadResult.Error(e)
}
}
class Repository(private val api: RepositoryApi,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO) {
suspend fun getRepositories(query: String, page: Int, perPage: Int): List
{
return withContext(dispatcher) {
api.search(query, page, perPage).repositories
}
}
suspend fun getTopContributor(ownerName: String, repoName: String): Contributor {
return withContext(dispatcher) {
api.getContributors(ownerName, repoName, 1).first()
}
}
}
Я понял, что загрузка блокируется, потому что библиотека подкачки вызывает ее из runBlockin
@JvmStatic
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun create(
pagingSource: PagingSource,
initialPage: PagingSource.LoadResult.Page?,
coroutineScope: CoroutineScope,
notifyDispatcher: CoroutineDispatcher,
fetchDispatcher: CoroutineDispatcher,
boundaryCallback: BoundaryCallback?,
config: Config,
key: K?
): PagedList {
val resolvedInitialPage = when (initialPage) {
null -> {
// Compatibility codepath - perform the initial load immediately, since caller
// hasn't done it. We block in this case, but it's only used in the legacy path.
val params = PagingSource.LoadParams.Refresh(
key,
config.initialLoadSizeHint,
config.enablePlaceholders,
)
runBlocking {
val initialResult = pagingSource.load(params)
when (initialResult) {
is PagingSource.LoadResult.Page -> initialResult
is PagingSource.LoadResult.Error -> throw initialResult.throwable
is PagingSource.LoadResult.Invalid ->
throw IllegalStateException(
"Failed to create PagedList. The provided PagingSource " +
"returned LoadResult.Invalid, but a LoadResult.Page was " +
"expected. To use a PagingSource which supports " +
"invalidation, use a PagedList builder that accepts a " +
"factory method for PagingSource or DataSource.Factory, " +
"such as LivePagedList."
)
}
}
}
else -> initialPage
}
return ContiguousPagedList(
pagingSource,
coroutineScope,
notifyDispatcher,
fetchDispatcher,
boundaryCallback,
config,
resolvedInitialPage,
key
)
}
Поэтому я добавляю viewModelScope для запуска неблокирующей сопрограммы, например
override suspend fun load(params: LoadParams): LoadResult {
try {
return scope.async {
val page = params.key ?: 1
// network call to get repositories
val repos = repository.getRepositories(query, page, 10)
val results = repos.map { repo ->
// uses repo to get its top contributor
val contributor = repository.getTopContributor(repo.owner.username,
repo.reponame)
Result(repo.owner.url, repo.reponame, contributor.username?: "")
}
return@async LoadResult.Page(
data = repoResults,
prevKey = if (page == 1) null else page-1,
nextKey = page + 1
)
}.await() as LoadResult
} catch (e: Exception) {
return LoadResult.Error(e)
}
}
К сожалению, прокрутка остается медленной, поэтому я спрашиваю
1. Правда ли, что загрузка по умолчанию выполняется в блокирующем режиме, несмотря на переключатель getRepositories и getTopContributor в Dispatchers.IO, в соответствии с Почему «withContext» не переключает сопрограммы в «runBlocking»? это
2. Поскольку мне нужно сделать 1 сетевой запрос для получения репозиториев, и каждому из этих репозиториев нужно найти своего основного участника, я делаю запросы page_size+1. Я ищу советы по улучшению производительности прокрутки, поскольку каждая страница зависит от этих сетевых запросов. Мой пейджер выглядит
val pagingData: Flow = Pager(
config = PagingConfig(pageSize = PAGE_SIZE, prefetchDistance = 4 * PAGE_SIZE),
pagingSourceFactory = { RepoResultPagingSource(repo, QUERY, viewModelScope) }
).flow.cachedIn(viewModelScope)
Подробнее здесь: [url]https://stackoverflow.com/questions/78433291/slow-scrolling-in-paging3-load-function[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия