[英]Why does this example of paging library perform much worse than just a recycler view?
So i've been reading on Android's new paging library. 因此,我一直在阅读Android的新分页库。 Specifically, I'm trying load a list of never-ending images (with Glide) using a recyclerview with adapter, viewmodel, and data source (backed by retrofit network calls). 具体来说,我正在尝试使用带有适配器,视图模型和数据源(由改造网络调用支持)的recyclerview加载永无休止的图像列表(使用Glide)。
Here's the base code: 这是基本代码:
// inside my activity
PhotosListAdapter adapter = new PhotosListAdapter(getApplicationContext());
PhotosViewModel viewModel = ViewModelProviders.of(this).get(PhotosViewModel.class);
viewModel.getPhotosList().observe(this, adapter::submitList);
RecyclerView recyclerView = findViewById(R.id.main_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
...
// My adapter code:
@Override
public void onBindViewHolder(@NonNull PhotoViewHolder photoViewHolder, int i) {
Photo photo = getItem(i);
if (photo != null) {
mGlide.load(photo.previewURL).into(photoViewHolder.mPhotoImageView);
}
}
private static final DiffUtil.ItemCallback<Photo> DIFF_CALLBACK = new DiffUtil.ItemCallback<Photo>() {
@Override
public boolean areItemsTheSame(@NonNull Photo photo, @NonNull Photo other) {
return photo.id == other.id; // these are just ints
}
@Override
public boolean areContentsTheSame(@NonNull Photo photo, @NonNull Photo other) {
return photo.previewURL.equals(other.previewURL); // this is just a string
}
};
...
// My View Model code:
private LiveData<PagedList<Photo>> mData;
public PhotosViewModel() {
PhotosDataSource photosDataSource = new PhotosDataSource();
mData = new LivePagedListBuilder<>(new DataSource.Factory<Integer, Photo>() {
@Override
public DataSource<Integer, Photo> create() {
return photosDataSource;
}
}, 25).build();
}
public LiveData<PagedList<Photo>> getPhotosList() {
return mData;
}
// My Data Source:
Call<SearchResult> search = mPixabayService.search(PixabayApi.api_key, "photo", 1, params.requestedLoadSize, true);
search.enqueue(new Callback<SearchResult>() {
@Override
public void onResponse(Call<SearchResult> call, Response<SearchResult> response) {
if (response.isSuccessful()) {
SearchResult body = response.body();
callback.onResult(body.hits, null, 2);
}
// TODO add error cases
}
@Override
public void onFailure(Call<SearchResult> call, Throwable t) {
}
});
@Override
public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) {
Call<SearchResult> result = mPixabayService.search(PixabayApi.api_key, "photo", (Integer)params.key, params.requestedLoadSize, true);
result.enqueue(new Callback<SearchResult>() {
@Override
public void onResponse(Call<SearchResult> call, Response<SearchResult> response) {
if (response.isSuccessful()) {
List<Photo> hits = response.body().hits;
callback.onResult(hits, (Integer)params.key + 1);
}
}
@Override
public void onFailure(Call<SearchResult> call, Throwable t) {
}
});
}
However, I've built the same example just using an adapter of static list of items, and that seems to scroll much smoother on my emulator. 但是,我只是使用静态项列表适配器构建了相同的示例,并且在我的模拟器上滚动起来似乎更加流畅。 Is there something i'm missing in my code? 我的代码中缺少什么吗?
Here are my suspicions for the factors behind what could be making it worse: 这是我对可能使情况变得更糟的背后因素的怀疑:
recyclerview.setHasFixedSize(true)
make sense in this case? 在这种情况下, recyclerview.setHasFixedSize(true)
有意义? (i did also notice images are different sizes when i scroll down and then come back to the original image - is there a way to prevent this?) (我确实还注意到,当我向下滚动然后返回到原始图像时,图像的大小是不同的?有没有办法防止这种情况?) DIFF_CALLBACK
? 这是因为DIFF_CALLBACK
中有些奇怪吗? i actually don't really know the purpose of this class that well 我真的不太了解这堂课的目的 viewModel.getPhotosList().observe(this, adapter::submitList);
is expected to be slower because it should invalidate the list (vs a static list); 预计速度会变慢,因为它会使列表无效(与静态列表相比); however, is this expected to cause like a 5x lag??! 但是,这会导致5倍的延迟吗? Of course a static list is going to be smoother- far less overhead. 当然,静态列表将更加平滑-开销要少得多。 If its an actual possibility, go with that. 如果实际可行,那就去吧。 You use a paged list when either holding the entire list in memory is not feasible, or when requesting the entire list from the data source (especially remote ones) would be too time consuming/costly. 当将整个列表保存在内存中不可行时,或者从数据源(尤其是远程数据源)请求整个列表太耗时/昂贵时,可以使用分页列表。
1)Depends on your UI. 1)取决于您的UI。 The fixed size is the size it takes on screen, not the size of the list. 固定大小是它在屏幕上显示的大小,而不是列表的大小。 Generally this is true for full sized lists or lists that don't grow/shrink with contents. 通常,对于全尺寸列表或不随内容增长/缩小的列表而言,这是正确的。
2)DiffUtil and its callback have nothing to do with paging, they pre-existed the paging library. 2)DiffUtil及其回调与分页无关,它们已预先存在分页库。 They diff lists around changes to make the most efficient calls to the adapter possible, rather than doing an entire notifyDataSetChanged. 它们围绕更改列出列表,以使对适配器的最有效调用成为可能,而不是执行整个notifyDataSetChanged。 But they do take up some time in doing so. 但是他们确实花了一些时间。 Its important that this be correct, otherwise you'll either miss notifications, or use less efficient ones. 重要的是要做到这一点正确,否则您将错过通知或使用效率较低的通知。
3)Expected to be slower vs what? 3)预计比什么慢? But anywhere you're using an observable you will see a slow down, you're posting messages between threads potentially. 但是在使用可观察对象的任何地方,您都会看到速度变慢,您可能会在线程之间发布消息。 That's one of the reasons they're horribly misused a lot of the time, people don't understand what they actually do. 这是他们很多时候被严重滥用的原因之一,人们不了解他们的实际工作。 Yes, a 5x slowdown doesn't seem unlikely, especially if you end up using the less efficent notifyDataSetChanged rather than more exact notifies. 是的,速度降低5倍似乎不太可能,尤其是如果您最终使用效率较低的notifyDataSetChanged而不是更精确的通知时。
4)When you fling, you load a lot more items more quickly. 4)猛扑时,您可以更快地装载更多物品。 Which could cause more remote loads. 这可能会导致更多的远程负载。 So if you're going to have an issue, it will be when you fling. 因此,如果您遇到问题,那将是您逃跑的时候。 Generally you want to preload on a separate thread far enough in advance it isn't an issue. 通常,您要提前足够长的时间在单独的线程上预加载,这不是问题。 Have your tried playing with the page size and prefetch distance? 您是否尝试过页面大小和预取距离?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.