@AllenCoder @limuyang2 看了下源码,这里是自己实现的?而 widget 包的 ListAdapter 用的是AsyncListDiffer,为什么没有直接用这个类呢?
如果是因为设计上的原因,需要自己重新写,那么想问下,为什么默认的方法:
DiffDemoCallback callback = new DiffDemoCallback(getNewList());
mAdapter.setNewDiffData(callback);
是同步的,而异步的需要写这么大段代码:
new Thread(new Runnable() {
@Override
public void run() {
final List<DiffUtilDemoEntity> newData = getNewList();
MyDiffCallback callback = new MyDiffCallback(newData, mAdapter.getData());
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback, false);
runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.setNewDiffData(diffResult, newData);
}
});
}
}).start();
而 widget 的 AsyncListDiffer 的方法submitList就是异步计算的(假设 list 比较大,比方说1000个,计算就很耗时)。
这里能否把默认的 setNewDiffData 改为异步的,或者简化一下异步方法的 API 呢?
谢谢你提出的建议,之前确实是忽略了AsyncListDiffer。之后会补上。
不过通过查看源码,是使用的Handler实现的,其本质和demo中的用法是一样的。
关于你说的demo上给的示例是一大段代码,这个你仔细看看,仅仅是因为Thread 和 runOnUiThread之间的切换。并且在项目中,并不会直接使用new Thread这种粗暴的写法,仅仅是作为使用示例。
在AsyncListDiffer的源码中,是通过配置AsyncDifferConfig来从外部传入mMainThreadExecutor主线池、mBackgroundThreadExecutor多线程池,以达到外部对于多线程的控制。
根据我的感觉,其实本demo中的写法,对于线程的管理更加灵活,你只需要告诉adapter结果就行,至于Diff的计算过程,adapter并不关心。
不好意思,刚刚对AsyncListDiffer进行了尝试,发现AsyncListDiffer属于一个高度封装的类,其内部对list进行了自己的管理,无法对外响应。onBindViewHolder的方法需要大改动,只能从mDiffer.getCurrentList()中拿出数据,本库的mData就等于无用,但是setNewData()等等方法,都是依赖于我们自己管理的数据mData,这种大改动显然是不合理的。
AsyncListDiffer的意思是,所有设置数据的方法,只有submitList这一个内部方法,不论新增还是删除,然后其内部对list进行了自己的管理。
本库也有自己的mData管理list,并且有setNewData()、addData()等等方法。此冲突无法解决。
并且AsyncListDiffer属于package android.support.v7.recyclerview.extensions;包下面的,并非属于基本api,而是属于一个扩展类。所以google的写法并无不问题,扩展类不是基础api,不需要考虑兼容问题。本库本质上也属于扩展库。扩展与扩展之间的冲突是正常的。
AsyncListDiffer的原理我上面也进行过解释,内部实现的很简单。现阶段可以自己实现异步,有更好的方式,例如:kotlin的协程。如果真的就想要google提供的简便方法,那请直接继承ListAdapter类。
后续我们会考虑加入简单的异步实现的,如需多线程管理,还是请按照demo中的示例,在外部进行线程管理,我们不想为了一个异步Diff,而在基类BaseQuickAdapter中封装一个线程池,过于繁重,因为不是每一个adapter都需要异步diff。
google的扩展ListAdapter类设计就是为了异步diff,所以内部封装线程池并无不妥。
不知我是否解释明白了
感谢详细的解释。那么没法实现一个比如 BaseQuickListAdapter 之类的吗
感谢详细的解释。那么没法实现一个比如 BaseQuickListAdapter 之类的吗
BaseQuickAdapter是所有类的父类,都是继承于此,只能在此基础上进行扩展
那么还是加入简单异步实现吧。同步方法感觉还是不要用为好
那么还是加入简单异步实现吧。同步方法感觉还是不要用为好
同步方法并没有太大性能问题,1w条数据以内,基本上都能在16ms内刷新
那么还是加入简单异步实现吧。同步方法感觉还是不要用为好
异步属于比较繁重的方法。异步和同步是互补的。不存在谁好谁坏。不同情况选择不同的方法而已
这么快吗,那可能我的担心多余了
这么快吗,那可能我的担心多余了
dev中已经添加了一个简便方法,可拉取dev并参考其中的demo
@limuyang2 单继承的话,那么 PagedListAdapter 打算怎么办呢?(Paging库)
Most helpful comment
dev中已经添加了一个简便方法,可拉取dev并参考其中的demo