首页 > 解决方案 > androidx.RecyclerView ListAdapter 很慢

问题描述

我正在使用ListAdapterRecyclerView 并且在某些情况下应用程序变得非常慢 - 它冻结了 10 秒,并列出了 1000 个项目。

情况是,首先我提交了一个包含 1000 个项目的列表(首先按预期快速提交),然后我再次提交相同的列表,但排序不同。

通过大量调试,我终于发现, ListAdapter 触发了 a notifyItemRangeChanged(0, 999),所以基本上是完整的列表。我在其他地方(这里这里)读到,不应该这样做,因为它会使 RecyclerView 变慢——这显然是正确的——但是,我不能影响 ListAdapter 的行为。

有没有人有解决方案?我不想再次删除 ListAdapter,因为对于大多数其他用例来说,它既快速又方便,可以自动执行各种动画等。

编辑 - 一些代码

代码没什么花哨的,基本上是这样的:

RecyclerView mListView;
EnryListAdapter mEntryListAdapter; // <-- extends ListAdapter<Entry, VH>
...
    mEntryListAdapter = new EntryListAdapter();
    mListView.setAdapter(mEntryListAdapter);
    mListView.setLayoutManager(new LinearLayoutManager(this));
    mListView.setHasFixedSize(true);
    ((DefaultItemAnimator) mListView.getItemAnimator()).setSupportsChangeAnimations(false);

    List<Entry> entryList = getEntryList(); // <-- list with 1000 entries

    mEntryListAdapter.submitList(entryList); // <-- first submit is fast

    entryList = getDifferentlySortedEntryList(); // <-- list with same entries, sorted differently

    mEntryListAdapter.submitList(entryList); // <-- freezes app for over 10 seconds

标签: androidandroid-recyclerviewlistadapter

解决方案


最后,我发现这是我自己的错误

在我的实施中,DiffUtil.ItemCallback<Entry>#areContentsTheSame我进行了以下检查:

oldItem.flags == newItem.flags

whereEntry.flagslong第一个,但后来我将其更改为 class 的实例,而没有更改此比较。由于实例不是相同的对象,因此这种比较false一直都会产生。将其替换为

ObjectsCompat.equals(oldItem.flags, newItem.flags)

解决了这个问题。


推荐阅读