Android Support库:AsynListUtil

    在介绍完 Android Support 库发展历程(http://blog.chengyunfeng.com/?p=1047)后, 再分别介绍下 Android Support 库中有用但是被忽略的一些功能。了解这些功能,在需要的时候可以避免在引入其他类似的第三方库或者避免自己重复制造轮子,提高开发效率。

    这是一系列的介绍文章,每次介绍 Support 库中的一个功能,篇幅尽可能的短,方便大家利用碎片时间阅读。

    这次介绍来自 recyclerview-v7 中的 AsyncListUtil 类。

RecyclerView

    RecyclerView 发布后大家应该都放弃使用 ListView 了。使用 RecyclerView 需要对数据控制的更精细,比如如果删除了某个位置的数据,则需要使用 RecyclerView.Adapter 的 notifyItemRemoved(int position) 函数来通知 RecyclerView 被删除的数据,这样 RecyclerView 就可以实现一个删除该条数据的动画,而 ListView 只要数据变化了,都只需要调用 notifyDataSetChanged() 即可。

    而在使用 RecyclerView 过程中数据来源是各种各样的,数据可以来自于网络、也可以是数据库、还可以是读取文件,不同的数据来源对 Adapter 的处理也是有差别的。本次介绍的 AsyncListUtil 适用于数据来源数据库或者本地磁盘的情况

AsyncListUtil

    AsyncListUtil 是一个用来异步加载数据的类。例如,如果你的数据是来至于数据库的,则可以使用 AsyncListUtil 在后台批量加载 Cursor 中的数据,当数据加载完成后在通知 UI 线程使用,并且 AsyncListUtil 支持数据缓存,这样可以实现非常流畅的滚动性能。

    AsyncListUtil 在后台线程加载数据,每次加载一批数据,数据的个数是可以配置的,并且在内存中缓存了一些数据来提高效率。

    AsyncListUtil 使用一个后台线程来加载数据,所以 AsyncListUtil 适合用来从磁盘加载数据的情况(比如,读取数据库、读取文件等),而不适合从网络获取数据的情况。

    AsyncListUtil 有如下四个函数可以使用:

  • T getItem (int position): 返回 position 位置的数据,如果数据尚未加载完成,则返回 null;
  • int getItemCount () 返回数据集的个数,该数值为 DataCallback.refreshData() 函数返回的值
  • void onRangeChanged () 更新当前数据可见范围,当 RecyclerView 滚动的时候,需要回调这个函数来告诉 AsyncListUtil 可见数据范围发生变化,需要根据当前新的可见数据范围来加载所需数据,在 RecyclerView 的 onScrolled(RecyclerView, int, int)) 中调用该函数即可。
  • void refresh () : 如果数据发生了变化, 调用该函数来强制重新加载数据,丢弃之前缓存的数据。
    AsyncListUtil 有两个回调函数分别处理数据加载和 UI 通知事件:AsyncListUtil.DataCallback 和 AsyncListUtil.ViewCallback。

AsyncListUtil.DataCallback

    DataCallback 类提供了在后台加载数据的功能,里面定义了如下四个函数,这些函数都是在后台线程中执行的:

  • int refreshData () : 刷新数据,返回新的数据个数,如果你所加载的数据来自于 Cursor,则当数据发生变化的时候,在这里从新生成一个 Cursor 并返回 Cursor 的数目。
  • void fillData (T[] data, int startPosition, int itemCount) :加载数据,其中 data 数组是加载后的数据,而 startPosition 是数据开始的位置,而 itemCount 是加载数据的 个数。 data 数组中的对象是可以重复利用的,如果 data[i] 的数据不为 null,则可以重复利用而无需重新创建数据对象。
  • int getMaxCachedTiles () : 返回缓存数量的限制,一般不用实现这个函数,默认实现即可。
  • void recycleData (T[] data, int itemCount) : 回收 fillData 中所创建的数据,如果你的数据包含需要回收的资源,则可以在这里处理。

    一般只需要实现 refreshData 和 fillData 函数即可。

AsyncListUtil.ViewCallback

    ViewCallback 类提供了和 RecyclerView 关联的接口,里面的函数都是在 UI 线程中调用的,该类同样定义了四个函数:

  • void onItemLoaded (int position) : 当 position 位置的数据加载完后会调用该函数;
  • void onDataRefresh () : 当数据集发生变化的时候调用;
  • void getItemRangeInto (int[] outRange) : 返回当前可见的数据范围,参数 outRange 数组长度为2, outRange[0] 为第一个可见数据的位置,outRange[1] 为 最后一个可见数据的位置;
  • void extendRangeInto (int[] range, int[] outRange, int scrollHint) 用来计算平滑滚动所需要加载的额外数据,一般不用实现这个函数,默认实现即可;

参考:
[1]. 示例代码 https://github.com/CattleFoot/RecyclerViewUtils
[2]. 官网文档 https://developer.android.google.cn/reference/android/support/v7/util/AsyncListUtil
[3]. 译文 http://blog.chengyunfeng.com/?p=1057
[4]. 分页加载ORM数据 https://blog.csdn.net/zhangphil/article/details/78661838