Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
panwj edited this page Jun 17, 2019 · 4 revisions

概览

 Paging配合RecyclerView更容易从数据源中高效优雅的加载所需数据,不会因为数据库数据量大而造成查询时间过长。
Paging库的优点:
1. 数据请求占用比较少的网络带宽和系统资源;
2. 在数据更新和刷新期间,app也能快速响应用户输入

库架构

库架构:分页库关键组件是PagedList类,该类异步加载app所需要的数据以及分页数据。这个类为app的其他架构组件提供了联系。分页库实现了观察者模式.

Data: 每个PagingList实例从DataSource为你的App提供最新的数据。数据流从你的app后台或者数据库流向PagingList对象。DataSource提供一个单一的元数据,Factory加载内容。 分页库支持支持很多app架构,包括独立数据库或者服务器网络数据。

UI: PagingList类和PagingListAdapter配合使用,加载items数据到RecyclerView中。这些类一起使用来获取和显示已经加载的数据,预加载以及观察数据变化并自动更新。

数据架构

支持的数据架构:仅从网络获取、仅从本地数据库获取、从网络和数据库同时获取

  1. 网络获取或本地数据库:都是异步实现数据加载 数据库获取时,观察数据库,数据库内容发生改变数据库就会pull一个新的PagedList。 RecyclerView加载本地数据,可以使用Room库。通过这种方式,当向数据库中添加、修改、删除数据,这些变化都会被观察到,从而触发UI自动刷新。 网络获取时,下拉刷新网络加载(后端不发送更新)时会pull一个新的PagedList并使旧的无效。从后台服务器获取,使用同步的Retrofit API加载网络数据到你的DataSource对象中。

  2. 网络和数据库同时获取 数据库是网络缓存的数据,ui从数据库加载数据,数据库没有在从网络获取,又在回调中请求网络,将获取到的数据插入数据库,ui订阅了数据库的更新,因此,新的数据会流向正在观察的ui,实现刷新。

    注意:分页库的DataSource对象不提供任何错误处理,因为不同app处理和展示错误的方式不同。如果一个错误发生,将错误传递给callback中,尝试后续重新请求

对比

当前实现分页加载的方法有两种,使用CursorAdapter;使用AsyncListUtil

  1. CursorAdapter 可以是ListView很容易的加载数据,但是他是运行在UI线程的,而且Cursor也会在页面上出现无效的现象。

  2. AsyncListUtil允许RecycleView基于position进行分页加载,但是不允许非position进行分页加载,在数据集中强制使用null作为修饰符。 Paging解决了这些问题。此库简化了请求数据的过程。

使用注意事项

  1. 在app Module的build.gradle中添加如下依赖:

`` dependencies { def paging_version = "1.0.0"

implementation "android.arch.paging:runtime:$paging_version"
// alternatively - without Android dependencies for testing
testImplementation "android.arch.paging:common:$paging_version"
 // optional - RxJava support, currently in release candidate
 implementation "android.arch.paging:rxjava2:1.0.0-rc1"
}
AndroidX(Android Jetpack)
dependencies {
 def paging_version = "2.0.0-beta01"
implementation "androidx.paging:paging-runtime:$paging_version"
// alternatively - without Android dependencies for testing
testImplementation "androidx.paging:paging-common:$paging_version"
 // optional - RxJava support
 implementation "androidx.paging:paging-rxjava2:$paging_version"
}
````java
  1. 在ui中实现占位: 在app获取到数据之前,如果想让ui显示列表,可以先像用户展示占位列表,默认情况下,placeHolder是开启的

占位有一下优点:

  1. 支持滚动条:PagingList提供了List item的数量给PagedListAdapter.这些信息允许Adapter绘制一个滚动条传达list的尺寸。当新的页数加载后,滚动条不会滚动,因为有的list没有改变尺寸。

  2. 没有加载Loading提示的必要:因为list尺寸已经知道了,没有必要告诉用户有更多的items正在被加载。placeholders已经传达了这些信息。

在使用占位支持之前,如下先决条件需要知道:

需要一个数据集大小是确定的:通过Room持久库获取的DataSource可以有效的确定它们的数量。如果你正在使用一个本地存储解决方案或者仅仅通过网路数据架构,那很可能无法确定你的数据集的数量。
需要Adapter触发未加载数据的加载:Adapter或者已存在的机制用于处理null items的情形。例如,当你bind数据到一个ViewHolder,你需要提供默认值给未加载的数据。
需要每个item有相同的view大小:如果对于社交网络更新(例如:聊天界面)item的大小依赖于内容。强烈建议你关掉placeholders功能。
  1. Paging配置可以通过如下属性设置完成:

`` a. Page size:每一页item数量。 b. Prefetch distance:预加载数量,通常是page size整数倍 c. Placeholder presence:是否启用占位功能。

PagedList.Config myPagingConfig = new PagedList.Config.Builder() .setPageSize(50) .setPrefetchDistance(150) .setEnablePlaceholders(true) .build();

DataSource.Factory<Integer, Concert> myConcertDataSource = concertDao.concertsByDate();

LiveData<PagedList<Concert>> concertList = new LivePagedListBuilder<>(myConcertDataSource, myPagingConfig) .setFetchExecutor(myExecutor) .build(); ````java

  1. 选择正确的数据源类型

    使用DataSource定义你需要提取分页的数据源。根据使用场景使用的不同使用它不同的子类,如下
    1. 使用PageKeyDataSource,让你加载的页面插入到下一个或者以前的key,例如:例如:你要从网络获取社交媒体的帖子,你就需要通过nextPage加载到后续的加载中。

    2. 使用ItemKeyDataSource,如果你需要让使用的数据的item从N条增加到N+1条请使用。例如:你需要从嵌套评论中获取一条评论,需要通过一条评论的ID获取下一条评论的内容。

    3. PositionalDataSource,如果你需要从事数据存储的任意位置来获取数据页,此类支持你从任意你选择的位置开始请求item的数据集。比如从第1200条返回20条item。

如果使用Room来管理数据,就要使用DataSource.Factory来初始化

  1. PagingList将数据加载进内存 PagedList类加载的数据来自于DataSource。你可以配置一次加载多少数据,可以预先获取多少数据,尽量减少加载数据的时间。此类也可以向其他类提供数据更新的信号,比如:RecycleView.Adapter一样,为RecycleView页允许数据加载。

PagedList数据加载机制:

  1. PagedListAdapter 类实现自RecycleView.Adapter,并且从PagedList中加载数据。例如:当一个新的页面被加载,PagedListAdapter就会发信号通知RecycleView数据已经加载完成,然后RecycleView就是显示和数据量相等的item,并执行适当的动画。

  2. PagedListAdapter对于来自一个PagedList的下一条数据会在后台线程进行计算。(例如:将数据库的新数据更新到PagedList中),调用notifyItem...()方法更新需要的数据列表的内容。然后RecycleView再执行必要的更改。例如:iitem的position的顺序的改变。

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /