前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android Architecture Paging Library详解 | Google I/O大会上的最新发布

Android Architecture Paging Library详解 | Google I/O大会上的最新发布

作者头像
京东技术
发布2018-07-30 16:17:17
1.5K0
发布2018-07-30 16:17:17
举报
文章被收录于专栏:京东技术

作 者 简 介

郭海生

Android高级工程师,6年以上开发经验,有丰富的代码重构和架构设计经验,负责京东商城我的京东的开发工作,热衷于学习和研究新技术。

>>>>

导读

美国当地时间2018年5月8日,Google I/O大会上发布了 Android Jetpack 。将之前发布的一系列组件比如 Lifecycle、LiveData、Room、ViewModel等进行融合从而推出了一套官方认证的开发体系Android Jetpack。这套体系分为架构(Architecture)、UI、基础(Foundation)以及行为(Behavior)四个方面。

谷歌官方架构组件图:

这次的Android Jetpack推出了五个新组件,它们分别是:Navigation(导航组件)、Paging(分页组件)、WorkManager(处理类似后台任务组件)、Slices(切片)、Android KTX(Kotiln扩展程序)

本文主要介绍的是Paging,关于Navigation的解析,可以查看《Android Jetpack 新组件之Navigation的用法和源码结构分析》

>>>>

背景

现有的 Android API 允许内容的分页,但是都有明显的限制和缺陷:

  • CursorAdapter(https://developer.android.com/reference/android/widget/CursorAdapter.html)使得获取数据库查询结果更加容易的映射到ListView项目中,但是它的查询操作是在UI线程上运行的,并且以低效的方式使用Cursor。
  • AsyncListUtil(https://developer.android.com/reference/android/support/v7/util/AsyncListUtil)允许把基于位置position的数据分页放进RecyclerView,但是不支持非位置position的数据,并且强制空数据集中的空位占位符。

>>>>

Paging Library详解

>>>> Paging Library 简介

The Paging Library makes it easier for youto load data gradually and gracefully within your app's RecyclerView.

Many apps consume data from a data sourcethat contains a large number of items, but only display a small portion at atime.

The Paging Library helps your app observeand display a reasonable subset of this data.

翻译】:

Paging library 可以让你渐进的加载数据到你的数据源,而且可以优雅的配合RecyclerView使用。

许多app经常性从大量数据源里加载数据,但是在某个时刻却只需要展示这些数据的一小部分。Paging library可以帮助你的app观察和展示一个合理的数据集合。

>>>> Paging Library 库的架构

从图中可以看出,Paging是围绕PagedList为中心的,遵循数据驱动的思想。

>>>> DataSource

DataSource<Key,Value>是PagedList的数据源类。Key相当于加载数据的条件信息,Value对应返回的结果。Paging提供了三种DataSource<Key,Value>的实现:

  1. PageKeyedDataSource<Key,Value>:适用于以页信息加载数据的场景。比如在网络加载数据的时候,需要传Next或者Previous作为键值参数。
  2. ItemKeyedDataSource<Key,Value>:适用于所加载的数据依赖其他现有数据信息的场景。比如加载第N+1条需要第N条的数据,这时候需要传第N条的数据过去。
  3. PositionalDataSource<T>:适用于数据总量固定,支持从特定位置加载数据的场景。比如返回从1200条开始的200条数据。

三种DataSource相同点:都有loadInitial()抽象方法,各自都封装了请求初始化数据的参数类型LoadInitialParams和接受请求参数的LoadInitialCallback。

不同点:PageKeyedDataSource和ItemKeyedDataSource需要实现loadBefore()和loadAfter()方法,而PositionalDataSource需要实现loadRange()方法。

可以看出,DataSource不是真正的数据源,而是负责从数据源加载数据,承担了PagedList与数据源之间的桥梁。

>>>> PagedList

PagedList从DataSource中获取数据,通过PagedList.Config 可以配置一次加载的数量以及预加载的数量,它也为RecyclerView.Adapter提供更新信号,驱动UI的刷新。它提供了五个成员变量如下:

  • mMainThreadExecutor:主线程的Executor, 可以将结果post到主线程。
  • mBackgroundThreadExecutor:后台线程的Executor。
  • BoundaryCallback:加载Datasource中的数据加载到边界时的回调。

PagedList.Config可配置的属性:

  1. setPageSize:设置每页加载的数量。
  2. setInitialLoadSizeHint:初始化数据时候加载数量。
  3. setPrefetchDistance:预加载数量,设置距离最后还剩多少个item开始加载下一页的数据。
  4. setEnablePlaceholders:当Item为null时是否使用PlaceHolder展示。
  5. PagedStorage<T>:用于存储加载到的数据,它包含一个ArrayList<List<T>>对象mPages,按页存储数据。

>>>> PagedListAdapter

PagedListAdapter继承于RecycleView.Adapter,用来在RecycleView中显示PagedList 的数据。当拖动RecycleView加载每一页数据的时候,PagedListAdaptert通过DiffUtil在后台线程计算PagedList细粒度的变化并返回给自己一个新的PagedList,然后调用自己的notifyItem……()做刷新等操作。

>>>> AsyncPageListDiffer

AsyncPageListDiffer是一个辅助类,可以将PagedList数据更方便的映射到PagedListAdapter里。我们通常都是用LiveData承载PagedList对象,当数据变化的时候通过Lifecycles能收到通知,我们可以调用PagedListAdapter的submitList(PagedList)方法更新数据。AsyncPageListDiffer能监听到PagedList的加载Callbacks,通过DiffUtils在后台线程可拿到最新的数据集合。AsyncPageListDiffer为我们提供了getItem(int)和getItemCount()方法,这个可以配合PagedListAdapter呈现数据。

>>>> Paging Library 加载数据流程

如上图所示,Paging加载数据是在后台线程进行的,加载完成后在主线程显示。

当创建LiveData<PagedList>时候,LiveData会新建一个线程从DataSource中加载数据(触发loadInitial()),DataSource加载到数据会更新PagedList,PagedList更新会通知PagedAdapter,PagedAdapter会利用DiffUtil对比现在的Item和更新的Item的差异,对比结束后会确定是否刷新UI。

刷新UI,UI显示会触发PagedAdapter的getItem操作,随即触发PagedList的loadAround方法从DataSource加载周围的数据。

可以看出,整个过程Paging内部实现了线程的切换,数据的预加载,所有联动都是在Paging中,使用者只用关心加载数据的具体实现。

>>>> Paging Library的使用方法

1、Gradle依赖

https://developer.android.com/topic/libraries/architecture/adding-components#paging

2、构造可观察的PagedList对象

userDao是model对象,可以从数据库取到User返回DataSource.Factory对象,我们将DataSource.Factory传给LivePagedListBuilder,并配置PagedList,可以返回一个LiveData对象

3、构建数据源对象

我们用DataSource建立分页数据源,实现了ItemKeyedDataSource对应的抽象方法,定义加载第一页以及后面每一页数据。

4、PagedListAdpater建立与数据的绑定

5、MainActivity初始化UI、订阅数据源状态从而更新UI

>>>>

总结

Paging Library通过配合Lifecycle、ViewModel、LiveData等组件的特性,为我们提供了一个简单、安全、灵活的分页加载组件,其核心思想上以数据为驱动,我们只需关心加载数据的具体实现,并且在用户体验上,Paging Library逐步从数据源加载信息,从而不会耗费过多的设备资源或是等待太长的时间。

>>>>

具体使用方法请参考

官网:

https://developer.android.com/topic/libraries/architecture/paging/

googlecodelabs关于paginglibrary的使用方法:

https://codelabs.developers.google.com/codelabs/android-paging/index.html

官方demo:

https://github.com/googlesamples/android-architecture-components/tree/master/PagingWithNetworkSample

特别鸣谢:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/0920/8533.html

---------------------END---------------------

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 京东技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • >>>> Paging Library 简介
  • >>>> Paging Library 库的架构
  • >>>> DataSource
  • >>>> PagedList
  • >>>> PagedListAdapter
  • >>>> AsyncPageListDiffer
  • >>>> Paging Library 加载数据流程
  • >>>> Paging Library的使用方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档