在RecycleView中有效地加载数据

时间:2016-01-27 13:33:10

标签: android performance android-asynctask android-recyclerview

我填充了一个数据列表,这个数据分3步加载,所以在第一步完成后,我已经向用户显示了数据。然后,每当数据加载状态发生变化时,我都会逐步更新UI ...

我使用RecyclerView来显示我的数据。我可以观察到,当单个步骤的加载非常快时,UI就会阻塞(特别是当用户当前滚动非常快时)...所以我需要对事件进行分组,并且每隔x ms只更新一次UI。 ..

通过测试我看到,每150毫秒更新一次UI看起来好看又快,不会导致任何明显的口吃。

但我不确定旧设备或其他设备的反应。

有没有人有这方面的经验,可以告诉我哪个价值会好?

一般问题

可能会更普遍地提出这个问题:在非常频繁地更新用户界面时,最好的频率是什么,以避免阻止用户界面?或者在再次更新UI之前等待的最短时间

2 个答案:

答案 0 :(得分:8)

您的问题非常有趣,有一些解决方法。我只是在这里提供了一些解决方案。

<强> 1。缓存数据

当用户滚动时,您的适配器将从数组,数据库或网络查询某些数据。由于性能低下,我想可能是一个问题,因为加载数据的时间很长。因此,解决此问题的最佳方法是缓存数据。

您可以使用LRUCache类在磁盘上使用DiskLRUCache将数据缓存到内存中。此问题有针对此问题的Android指南:Caching bitmap

Psuedo代码:

if (memoryCache.get(key)) {
   // load data from memory and assign to cell
} else if (diskCache.get(key)) {
   // load data from disk and assign to cell
} else {
  // get data from database or network
  // assign to cell
  // save to memory cache
  // save to disk cache
}

<强> 2。使用不同的线程加载数据

当您处理长时间运行的任务影响您的UI时,您应该推迟到UI线程并为您的目的创建新线程。您可以使用Asynctask来实现此目的。

此方法的问题是:从后台加载数据时,滚动事件在屏幕上显示的单元格需要不同的数据。因此,当旧的asynctask对象完成工作时,它会将旧数据分配给您的单元格。的 BUMP !!! 即可。所以你必须仔细控制你的细胞状态。有一个很好的教程:Process Image Loading In Different Thread

第3。简化您的观点

如果您在滚动时不使用数据库处理,网络请求等问题,可能问题是您的视图过于复杂。您应该使用此工具:Hierarchy Viewer来检查哪个布局文件存在性能问题。您还可以使用工具GPU Overdraw tool来检查视图中的许多部分是否已经绘制了许多不必要的东西。

<强> 4。根据帧速率检测更新数据的时间

您必须始终将帧速率保持在60fps以下。使用该帧速率,用户将无法识别滞后,笨拙......在您的视图中。您可以使用GPU Profiler来检查帧速率。根据该帧速率,您将决定是否应简化视图,优化onDraw方法或优化GPU绘图(由于过度绘制)以保持UI帧速率<= 60fps。

我已将所有上述方法集成到名为ImageUploader的项目中。此应用程序将图像上传到Flickr服务并显示所有上传图像的列表或查看单个图像。

谷歌上传了一系列Android Performance Pattern教你许多有用的东西,比如缓存,批处理,有用的提示......

希望这有帮助:)

答案 1 :(得分:0)

我知道该职位很旧。但是,如果仍然有人想在RecycleView中有效地处理“加载数据”,请尝试使用此库https://github.com/mrHerintsoaHasina/picassiette。听起来像Picasso或Glide,但也支持自定义数据(不仅是位图)。您必须将项目迁移到androidx。