Paging2之PagedList 个人小结

来源:5-8 paging框架工作原理2【难点】

慕慕6500093

2022-11-17

– 吐槽:mooc好像有字数限制,总报系统异常,所以分开写。

二、PagedList

All data in a PagedList is loaded from its DataSource.Creating a PagedList loads the first chunk of data from the DataSource immediately, and should for this reason be done on a background thread. 
也就是说,PagedList中的所有数据都从其DataSource加载的。创建PagedList会立即从DataSource加载第一块数据(这个在上面讲过PagedList.create时会调用compute()触发loadInitial()执行)

A PagedList initially presents this first partial load as its content, and expands over time as content is loaded in. When loadAround is called, items will be loaded in near the passed list index. If placeholder nulls are present in the list, they will be replaced as content is loaded. If not, newly loaded items will be inserted at the beginning or end of the list.
PagedList最初将第一个部分加载作为其内容,并随着内容的加载而扩展。当调用loadAround时,将在传递的列表索引附近加载项。如果列表中存在占位符空值,则它们将在加载内容时被替换。如果没有,新加载的项目将插入列表的开头或结尾。

PagedList can present data for an unbounded, infinite scrolling list, or a very large but countable list. Use PagedList.Config to control how many items a PagedList loads, and when.
PagedList可以为无限滚动列表或非常大但可计数的列表显示数据。使用PagedList.Config可以控制PagedList加载参数。

If you use LivePagedListBuilder to get a androidx.lifecycle.LiveData<PagedList>, it will initialize PagedLists on a background thread for you.
也就是使用LivePagedListBuilder将PagedList作为泛型参数传递给“这个可感知生命周期”的消息订阅组件LiveData,并且LivePagedListBuilder.build时在后台线程初始化PageList。
先看下这个LivePagedListBuilder.build干了啥:
@NonNull
   @SuppressLint("RestrictedApi")
   public LiveData<PagedList<Value>> build() {
   // 传入几个参数:初始化加载的key,PagedList.Config,边界回调callback,DataSource.Factory,
   // notifyExecutor(接收pagedlist更新),mFetchExecutor(指定从哪个线程池获取分页数据)
       return create(mInitialLoadKey, mConfig, mBoundaryCallback, mDataSourceFactory,
               ArchTaskExecutor.getMainThreadExecutor(), mFetchExecutor);
   }
   
原来是创建了一个LiveData<PagedList<T>>,这一下就把PagedList和LiveData关联起来了。
@AnyThread
   @NonNull
   @SuppressLint("RestrictedApi")
   // 注意这是个私有方法,仅供LivePagedListBuilder.build()调用
   private static <Key, Value> LiveData<PagedList<Value>> create(
           @Nullable final Key initialLoadKey,
           @NonNull final PagedList.Config config,
           @Nullable final PagedList.BoundaryCallback boundaryCallback,
           @NonNull final DataSource.Factory<Key, Value> dataSourceFactory,
           @NonNull final Executor notifyExecutor,
           @NonNull final Executor fetchExecutor) {
       return new ComputableLiveData<PagedList<Value>>(fetchExecutor) {
           @Nullable
           private PagedList<Value> mList;
           @Nullable
           private DataSource<Key, Value> mDataSource;
           private final DataSource.InvalidatedCallback mCallback =
                   new DataSource.InvalidatedCallback() {
                       @Override
                       public void onInvalidated() {
                           invalidate();
                       }
                   };
                  
           @SuppressWarnings("unchecked") // for casting getLastKey to Key
           @Override
           // 注意这个ComputableLiveData对象的方法compute(),
           // 它用于创建 PagedList/DataSource,
           // 也是触发上面说的DataSource.loadInitial()执行的核心。
           protected PagedList<Value> compute() {
               @Nullable Key initializeKey = initialLoadKey;
               if (mList != null) {
                   initializeKey = (Key) mList.getLastKey();
               }
               do {
                   if (mDataSource != null) {
                       mDataSource.removeInvalidatedCallback(mCallback);
                   }
                   // 创建数据源对象
                   mDataSource = dataSourceFactory.create();
                   // 监听数据源失效
                   mDataSource.addInvalidatedCallback(mCallback);
                   // 构建PagedList对象
                   mList = new PagedList.Builder<>(mDataSource, config)
                           .setNotifyExecutor(notifyExecutor)
                           .setFetchExecutor(fetchExecutor)
                           .setBoundaryCallback(boundaryCallback)
                           .setInitialKey(initializeKey)
                           .build();// 触发dispatchLoadInitial执行
               } while (mList.isDetached());// 保证PagedList和mDataSource始终是一对
               return mList;
           }
       }.getLiveData();//注意返回的是livedata对象,不是ComputableLiveData对象哦
   }

大致逻辑:ComputableLiveData是一个持有mLiveData对象抽象类,通过暴露compute方法,LivePagedListBuilder为其提供创建 PagedList/DataSource对象实例化的实现,并对ComputableLiveData的mRefreshRunnable、mInvalidationRunnable的实现细节进行隐藏,仅暴露一个它持有的mLiveData对象。这样一来,外界只需要关心这个泛型为PagedList的LiveData对象,PagedList对外将毫无存在感,就是个存放来自DataSource数据的list罢了,这样LiveData的逼格又上个了台阶。

写回答

1回答

LovelyChubby

2022-11-23

真棒的你
0
0

开发商业级热门短视频App 掌握Jetpack组件库

Jetpack架构大揭秘,全组件实战主流且功能完整的短视频App

1364 学习 · 607 问题

查看课程