gpt4 book ai didi

java - PagedList 在使用 Room 的 Android 应用中不断增长但从未缩小

转载 作者:行者123 更新时间:2023-11-29 23:30:58 25 4
gpt4 key购买 nike

在我的 Android 应用程序中,我有一个非常基本的 RecyclerView 实现,它使用 Room 显示数据库中的条目。与 Paging library .

从数据库中获取条目的 Dao 方法:

@Query("SELECT * FROM entries")
abstract fun findAll(): DataSource.Factory<Int, Entry>

这就是在我的 ViewModel 中从返回的 DataSource.Factory 构造 LiveData 的方式:

private val config = PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setInitialLoadSizeHint(512)
.setPrefetchDistance(256)
.setPageSize(256)
.build()

val entries = LivePagedListBuilder(entryService.findAll(), config).build()
// (entryService here just calls through to the Dao)

我只是观察这个 LiveData 并将更新后的 PagedList 传递给我的 RecyclerView.Adapter

对应的RecyclerView.Adapter fragment :

private val differ = AsyncPagedListDiffer<Entry>(this, DIFF_CALLBACK)

fun submitList(list: PagedList<Entry>) {
differ.submitList(list)
}

(我不使用 PagedListAdapter,因为稍后我需要在我的适配器中进行更细粒度的控制)

看似一切正常,但当我开始监控应用程序的内存使用情况时,我开始怀疑 PagedList 项目未正确处理。

我在 submitList() 中添加了以下 Callback:

list.addWeakCallback(differ.currentList?.snapshot(), object : PagedList.Callback() {
override fun onChanged(position: Int, count: Int) {
Log.d("_tag", "Position: $position | Changed: $count" +
" | Size: ${list.size}")
}

override fun onInserted(position: Int, count: Int) {
Log.d("_tag", "Position: $position | Inserted: $count" +
" | Size: ${list.size}")
}

override fun onRemoved(position: Int, count: Int) {
Log.d("_tag", "Position: $position | Removed: $count" +
" | Size: ${list.size}")
}
})

在此之后,我向数据库中插入了 5000 个条目,相应的日志条目如下:

D/_tag: Position: 0 | Inserted: 512 | Size: 512

很好,这是预期的输出。

但是当我开始在列表中向下滚动时,日志条目如下:

D/_tag: Position: 512 | Inserted: 256 | Size: 768

D/_tag: Position: 768 | Inserted: 256 | Size: 1024

D/_tag: Position: 1024 | Inserted: 256 | Size: 1280

D/_tag: Position: 1280 | Inserted: 256 | Size: 1536

然后日志就停在这里,不再有日志条目,无论我在这一点之后向下滚动多少。

我对这种行为的疑问:

  • 为什么从不调用 onRemoved()

    PagedList 是否是一个不断增长的列表并且项目保留在内存中?

    分页的目的不就是按需加载新条目并删除旧的(不可见的)条目吗?

  • 为什么日志在第 1536 个条目后停止,即使我滚动到该条目之前也是如此?

    奇怪的是,条目显示正确,即使一直滚动到列表底部也是如此。

如果有人能向我解释这种行为,我将不胜感激。

(也欢迎 Java 回答)

编辑:

整个适配器的代码:

class EntryListAdapter
: RecyclerView.Adapter<EntryListAdapter.EntryViewHolder>() {

private val differ = AsyncPagedListDiffer<Entry>(this, DIFF_CALLBACK)

fun submitList(list: PagedList<Entry>) {
differ.submitList(list)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
EntryViewHolder {
val inflater = LayoutInflater.from(parent.context)
val entryItemView = inflater.inflate(R.layout.item_entry, parent, false)

return EntryViewHolder(entryItemView)
}

override fun onBindViewHolder(holder: EntryViewHolder, position: Int) {
differ.getItem(position)?.let { holder.bindTo(it) }
}

override fun getItemId(position: Int): Long {
return differ.getItem(position)?.id ?: RecyclerView.NO_ID
}

override fun getItemCount(): Int {
return differ.currentList?.size ?: 0
}

inner class EntryViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView) {

fun bindTo(entry: Entry) {
itemView.textEntryTitle.text = entry.title
}
}

companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Entry>() {
override fun areItemsTheSame(entry1: Entry, entry2: Entry): Boolean {
return entry1.id == entry2.id
}

override fun areContentsTheSame(entry1: Entry, entry2: Entry): Boolean
{
return entry1 == entry2
}
}
}
}

EDIT2:

承载 RecyclerViewFragment 的布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mainRecyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

最佳答案

Android 架构组件团队的 Chris Craik 刚刚确认 Reddit到目前为止,Paging 库不会丢弃分页数据(但它即将到来):

It is merged (1 and 2), but we haven't released it yet due to being extra-careful during the AndroidX switchover. Arch had to be careful to avoid causing regressions during an AndroidX migration (since those migrations are complex enough).

Now that AndroidX is stable, we can do the release, so we'll see about having it out soon.

关于java - PagedList 在使用 Room 的 Android 应用中不断增长但从未缩小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52676470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com