电视列表数据局部刷新方法、存储介质、电子设备及系统
技术领域
本发明涉及列表控件技术领域,具体涉及一种电视列表数据局部刷新方法、存储介质、电子设备及系统。
背景技术
在Android应用中,列表控件(ListView、GridView、RecyclerView)是使用最为频繁的控件之一,列表控件作为大批量数据展示窗口,不仅需要具备滑动加更多数据的特性,还需具备快速刷新数据的机制以满足用户快速浏览和查找数据的需求。
列表快速数据刷新又分为全列表刷新(FLDR)和局部刷新(LLDR)两种:
FLDR简单易用,其原理是先清空列表所有数据,然后填充所有数据,在数据量少的列表场景下,FLDR使用非常广泛,但其简单粗暴的特点也带来了刷新数据慢,且刷新过程中需要清空列表,导致列表存在“空白期”,用户体验差,而且刷新耗时;
LLDR使用复杂,需要编写特定的新老数据差异比较算法,使用和学习过程较为陡峭,优点是由于无须清空列表数据,因此无痕刷新数据,中间没有FLDR的空白期,使用算法进行差异比较,只刷新存在差异的地方,因此刷新数据快;
目前实现LLDR的方式是使用SortedList结合列表适配器,也就是常见的LLDR方式。SortedList是Java语言中一种在内部维护两个数组以将数组存储到列表中的数据结构。但这种方式不是真正意义上的局部刷新,LLDR是在比较差异后对列表单个ItemView进行刷新,因此也将ItemView中不存在差异的区域做了刷新,属于无意义刷新。例如,列表ItemView中只需刷新背景图片和在线观看人气数量,而底部标题属于无意义刷新区域,而LLDR是将整个ItemView进行刷新,包括标题文字。即目前,无论是FLDR还是LLDR,都不能很好的实现正真意义上的局部刷新。
发明内容
针对现有技术中存在的缺陷,本发明解决的技术问题为实现高效局部刷列表,保证列表中非刷新区域的数据不受影响。
为达到以上目的,本发明采取的技术方案是:一种电视列表数据局部刷新方法:
周期性将列表刷新区域对应的数据封装成刷新数据集合,每次封装成刷新数据集合时必须同一类数据的索引值一一对应;
对新、旧刷新数据集合进行克隆,并分别存储至两个不同的SortedList集合中,所述新刷新数据集合为从服务器请求的且尚未绑定至列表控件中的刷新数据集合,所述旧刷新数据集合为已绑定至列表控件中的刷新数据集合;
设置工作线程,在该工作线程中读取两个所述SortedList集合中的新、旧数据,使用EM Diff算法计算出新、旧数据中存在差异的数据,再将新、旧数据存在差异的数据及其索引值输出作为差异数据;
将差异数据加入消息队列中,主线程从所述消息队列中轮询读取差异数据并发送给列表适配器;
使用列表适配器更新当前列表数据中与所述差异数据的索引值对应的列表数据。
在上述技术方案的基础上,使用EM Diff算法计算出新、旧数据中存在差异的数据的方法为:
比较新旧数据的数据条目是否相同;
新旧数据的数据条目时,比较新旧数据同一数据条目的属性值是否相同;
若相同,不作处理;若不同,获取新旧数据同一数据条目的属性值差值作为新、旧数据差值。
在上述技术方案的基础上,使用Handler函数将差异数据加入消息队列中。
在上述技术方案的基础上,使用列表适配器仅更新当前列表数据中与所述差异数据的索引值对应的数据的方法为:
读取差异数据的索引值;
比较当前列表数据中是否存在索引值与差异数据的索引值相同;若是,更新当前列表数据中与所述差异数据的索引值对应的列表数据;若否,继续读取下一个差异数据的索引值,直至遍历完全部差异数据。
本发明还公开了一种存储介质,该存储介质上存储有计算机程序:所述计算机程序被处理器执行时实现所述的电视列表数据局部刷新方法。
本发明还公开了一种电子设备,包括存储器和处理器,存储器上储存有在处理器上运行的计算机程序,其特征在于:处理器执行计算机程序时实现所述的电视列表数据局部刷新方法。
本发明还公开了一种电视列表数据局部刷新系统,包括:
数据封装模块,其用于周期性将列表中刷新区域对应的数据封装成刷新数据集合,每次封装成刷新数据集合时必须同一类数据的索引值一一对应;
差异生成模块,其用于对新、旧刷新数据集合进行克隆,并分别存储至两个不同的SortedList集合中,所述新刷新数据集合为从服务器请求的且尚未绑定至列表控件中的刷新数据集合,所述旧刷新数据集合为已绑定至列表控件中的刷新数据集合;设置工作线程,在该工作线程中读取两个所述SortedList集合中的新、旧数据,使用EM Diff算法计算出新、旧数据中存在差异的数据,再将新、旧数据存在差异的数据及其索引值输出作为差异数据;
差异反馈模块,其用于将差异数据加入消息队列中,主线程从所述消息队列中轮询读取差异数据并发送给列表适配器;
差异更新模块,其用于使用列表适配器仅更新当前列表数据中与所述差异数据的索引值对应的列表数据。
在上述技术方案的基础上,所述差异生成模块用于:
比较新旧数据的数据条目是否相同;
新旧数据的数据条目时,比较新旧数据同一数据条目的属性值是否相同;
若相同,不作处理;若不同,获取新旧数据同一数据条目的属性值差值作为新、旧数据差值。
在上述技术方案的基础上,所速差异反馈模块使用Handler函数将差异数据加入消息队列中。
在上述技术方案的基础上,所述差异更新模块用于:
读取差异数据的索引值;
比较当前列表数据中是否存在索引值与差异数据的索引值相同;若是,更新当前列表数据中与所述差异数据的索引值对应的列表数据;若否,继续读取下一个差异数据的索引值,直至遍历完全部差异数据。
与现有技术相比,本发明的优点在于:
本发明将列表中刷新区域对应的新、旧数据进行克隆后,使用EM Diff算法进行新、旧数据的差异计算;计算出差异数据后,使用列表适配器仅更新当前列表数据中与差异数据的索引值对应的列表数据,从而实现真正意义上的局部刷新,保证列表中非刷新区域的数据不受影响;使用SortedList结合列表适配器进行刷新,刷新过程中无须清空列表,不会出现列表空白期。
附图说明
图1为本发明实施例中电视列表数据局部刷新方法的流程示意图;
图2为本发明实施例中电子设备的连接框图。
具体实施方式
以下结合附图及实施例对本发明作进一步详细说明。
参见图1所示,本发明实施例提供一种电视列表数据局部刷新方法:
S1,周期性将列表刷新区域对应的数据封装成刷新数据集合,每次封装成刷新数据集合时必须同一类数据的索引值一一对应。
首先列表控件需要进行刷新的区域及其对应的数据,例如:背景封面图(backPicUrl)、标题(title)、人气值(hotValues)等三个,房间主播名称为固定值。筛选出列表刷新区域对应的数据后,需要封装成刷新数据集合JavaBean,同时后续操作中需要进行跨进程数据传递。JavaBean需要实现Serializable接口,JavaBean与backPicUrl、title、hotValues的关系见如下表所示:
表1 房间RoomInfo的差异集合JavaBean
S2,对新、旧刷新数据集合进行克隆,并分别存储至两个不同的SortedList集合中,所述新刷新数据集合为从服务器请求的且尚未绑定至列表控件中的刷新数据集合,所述旧刷新数据集合为已绑定至列表控件中的刷新数据集合。
局部刷新要求对比新、旧数据的差异高效完成,无论是FLDR还是LLDR都是采用HashSet来作为集合框架存储数据,由于HashSet数数据结构存在排序慢得问题,本发明用SortedList作为新、旧数据的存储集合框架,在存储新、旧数据时必须保持新、旧数据的索引值一一对应,通过比较新旧数据的hash值来保证对比数据一一对应。
S3,设置工作线程,在该工作线程中读取两个SortedList集合中的新、旧数据,使用EM Diff算法计算出新、旧数据中存在差异的数据,再将新、旧数据存在差异的数据及其索引值输出作为差异数据。
本发明实施例构建一个名为差异回调器的Callback抽象类,差异回调器中会对新、旧刷新数据集合进行克隆,并分别存储至SortedList集合中,差异回调器需要所包含的功能函数有:读取新旧数据的大小、对比新旧Item是否为同一Item、对比新旧Item的属性值是否相同、获取对比差异属性的增量值。如下表所示:
表2 回调器
EM Diff算法(Eugene Myers'Diff Algorithm),亚丽桑州立大学计算机科学教授的差异比较算法。
根据EM Diff差异算法的原理,在有1000条数据且差异数据在200条以上时,差异对比的生产工作应放在非UI线程中进行,因此本发明实施例采取在工作线程中(一种非UI线程)进行差异数据的生产,整个差异数据生产步骤分以下四步:
Step1.克隆新、旧刷新数据集合并分别存储在两个不同的SortedList集合中,开辟一条工作线程进行差异数据的对比生产,该工作线程需要进行加锁处理,防止因并发访问导致的差异计算出现混淆;
Step2.在工作线程中创建EM Diff算法,将SortedList集合加入DiffUtil的Snake容器中,等待差异数据循环输出;
Step3.使用EM Diff算法计算出新、旧数据中存在差异的数据的方法为:
比较新旧数据的数据条目是否相同;
新旧数据的数据条目时,比较新旧数据同一数据条目的属性值是否相同;
若相同,不作处理;若不同,获取新旧数据同一数据条目的属性值差值作为新、旧数据差值。
使用Handler函数将差异数据加入消息队列中。
Step4.将生产输出的差异数据注入差异集合,为防止所以混乱,需要将每条差异数据打上标签,标签即为数据的索引值,方便后续数据刷新时索引值对比;
Step5.使用Handler将差异数据包装至消息中,并将消息加入消息队列中,等待UI线程抽取消息。
S4,将差异数据加入消息队列中,主线程从消息队列中轮询读取差异数据并发送给列表适配器。
新、旧数据的差异数据计算是耗时操作,为防止主线程阻塞,需要将差异数据计算放在工作线程中进行。由于工作线程与主线程之间无法直接访问对方的数据,为使主线程确切知道工作线程何时完成差异数据计算,因此需要工作线程将计算好的差异数据放入一个消息队列中,而主线程通过不断去轮询消息队列,如果息队列里面有消息就读取差异数据并发送给列表适配器,并进行后续的局部刷新操作。
由于列表存在静止和动态滑动两种状态,因此,列表在接收消息队列反馈的差异数据消息时需要不断轮询抓取的方式来获取差异数据消息,然后从差异数据消息中拆取差异数据,并设置给列表适配器。
S5,使用列表适配器更新当前列表数据中与差异数据的索引值对应的列表数据。
列表适配器接受到差异数据,会调取列表刷新函数进行刷新,为防止列表进行全刷新,需要新建一个ViewHolder进行差异数据与列表数据的绑定工作:
Step1.首先会读取差异数据中每条的数据索引值;
Step2.然后对比当前列表数据的索引值与差异数据的索引值是否相同,如果相同就去除差异数据中对应索引值的数据对象并绑定至当前列表数据上;如果不同,则继续滑动到下一条差异数据,直至直至遍历完全部差异数据。
本发明实施例还公开了一种存储介质,该存储介质上存储有计算机程序:计算机程序被处理器执行时实现电视列表数据局部刷新方法。需要说明的是,存储介质包括U盘、移动硬盘、ROM(Read-Only Memory,只读存储器)、RAM(Random Access Memory,随机存取存储器)、磁碟或者光盘等各种可以存储程序代码的介质。
参见图2所示,本发明实施例还公开了一种电子设备,包括存储器和处理器,存储器上储存有在处理器上运行的计算机程序:处理器执行计算机程序时实现电视列表数据局部刷新方法。
本发明实施例还公开了一种电视列表数据局部刷新系统,包括:
数据封装模块,其用于周期性将列表中刷新区域对应的数据封装成刷新数据集合,每次封装成刷新数据集合时必须同一类数据的索引值一一对应;
差异生成模块,其用于对新、旧刷新数据集合进行克隆,并分别存储至两个不同的SortedList集合中,所述新刷新数据集合为从服务器请求的且尚未绑定至列表控件中的刷新数据集合,所述旧刷新数据集合为已绑定至列表控件中的刷新数据集合;设置工作线程,在该工作线程中读取两个SortedList集合中的新、旧数据,使用EM Diff算法计算出新、旧数据中存在差异的数据,再将新、旧数据存在差异的数据及其索引值输出作为差异数据;
差异反馈模块,其用于将差异数据加入消息队列中,主线程从消息队列中轮询读取差异数据并发送给列表适配器;
差异更新模块,其用于使用列表适配器仅更新当前列表数据中与差异数据的索引值对应的列表数据。
其中,差异生成模块用于:
比较新旧数据的数据条目是否相同;
新旧数据的数据条目时,比较新旧数据同一数据条目的属性值是否相同;
若相同,不作处理;若不同,获取新旧数据同一数据条目的属性值差值作为新、旧数据差值。
所速差异反馈模块使用Handler函数将差异数据加入消息队列中。
差异更新模块用于:
读取差异数据的索引值;
比较当前列表数据中是否存在索引值与差异数据的索引值相同;若是,更新当前列表数据中与差异数据的索引值对应的列表数据;若否,继续读取下一个差异数据的索引值,直至遍历完全部差异数据。
本发明不局限于上述实施方式,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也视为本发明的保护范围之内。本说明书中未作详细描述的内容属于本领域专业技术人员公知的现有技术。