簡體   English   中英

為什么此分頁庫示例的性能遠不只是回收者視圖?

[英]Why does this example of paging library perform much worse than just a recycler view?

因此,我一直在閱讀Android的新分頁庫。 具體來說,我正在嘗試使用帶有適配器,視圖模型和數據源(由改造網絡調用支持)的recyclerview加載永無休止的圖像列表(使用Glide)。

這是基本代碼:

// 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) {

        }
    });
}

但是,我只是使用靜態項列表適配器構建了相同的示例,並且在我的模擬器上滾動起來似乎更加流暢。 我的代碼中缺少什么嗎?

這是我對可能使情況變得更糟的背后因素的懷疑:

  1. 在這種情況下, recyclerview.setHasFixedSize(true)有意義? (我確實還注意到,當我向下滾動然后返回到原始圖像時,圖像的大小是不同的?有沒有辦法防止這種情況?)
  2. 這是因為DIFF_CALLBACK中有些奇怪嗎? 我真的不太了解這堂課的目的
  3. viewModel.getPhotosList().observe(this, adapter::submitList); 預計速度會變慢,因為它會使列表無效(與靜態列表相比); 但是,這會導致5倍的延遲嗎?
  4. 我注意到我在模擬器上跑得很快,在靜態recyclerview上這似乎不是問題; 但是,LivePage對其竄動檢測是否有所不同? 我猛撲時屏幕似乎發瘋了。 換句話說,我感覺到的“來自分頁庫的鋸齒性能”是否僅是因為我上下浮動(而不是緩慢地上下滾動)?
  5. 我只是在某個地方缺少關鍵配置設置嗎?

當然,靜態列表將更加平滑-開銷要少得多。 如果實際可行,那就去吧。 當將整個列表保存在內存中不可行時,或者從數據源(尤其是遠程數據源)請求整個列表太耗時/昂貴時,可以使用分頁列表。

1)取決於您的UI。 固定大小是它在屏幕上顯示的大小,而不是列表的大小。 通常,對於全尺寸列表或不隨內容增長/縮小的列表而言,這是正確的。

2)DiffUtil及其回調與分頁無關,它們已預先存在分頁庫。 它們圍繞更改列出列表,以使對適配器的最有效調用成為可能,而不是執行整個notifyDataSetChanged。 但是他們確實花了一些時間。 重要的是要做到這一點正確,否則您將錯過通知或使用效率較低的通知。

3)預計比什么慢? 但是在使用可觀察對象的任何地方,您都會看到速度變慢,您可能會在線程之間發布消息。 這是他們很多時候被嚴重濫用的原因之一,人們不了解他們的實際工作。 是的,速度降低5倍似乎不太可能,尤其是如果您最終使用效率較低的notifyDataSetChanged而不是更精確的通知時。

4)猛撲時,您可以更快地裝載更多物品。 這可能會導致更多的遠程負載。 因此,如果您遇到問題,那將是您逃跑的時候。 通常,您要提前足夠長的時間在單獨的線程上預加載,這不是問題。 您是否嘗試過頁面大小和預取距離?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM