【问题标题】:Listview with big image is very slow具有大图像的列表视图非常慢
【发布时间】:2013-12-16 06:13:27
【问题描述】:

我正在开发一个 Android 应用程序。该应用程序有一个列表视图,每个项目都包含要显示的图像。一个屏幕通常可以包含大约 3 个图像。我正在使用一些真实相机捕获的未压缩图像进行测试,每个图像大约 1.5M 左右。事实证明,滚动真的很慢而且卡住了。我想知道这是因为 Android 操作系统的实现,还是我的用法有误?

详情如下:

在 Listview 中,我有一个 ViewHolder 来保存所有项目实例,因此它比 findViewById 更快。在这个列表视图的活动加载时,我将旋转几个图像加载器 AsyncTasks 来帮助加载图像。我的图像加载器是作为单例实现的,并且有两级缓存。一级缓存是MapSoftReference

private Map<String, SoftReference<Bitmap>> l1ImageCache = 
        new HashMap<String, SoftReference<Bitmap>>();

二级缓存是一个缓存文件夹。如果缓存无法命中,代码将执行异步下载并更新视图。整个 LoadImage 代码路径在我的 AsyncTask 实现中,并且是 UI 线程的一部分。

问题是,似乎缓存工作正常,并且图像加载非常快(从内存加载大约需要 10 毫秒),但滚动仍然卡住。

12-15 21:56:46.622: I/Choreographer(5803): Skipped 62 frames!  The application may be doing too much work on its main thread.

如果我将图像从每个 1M 更改为每个 100K,图像视图变得非常流畅。

我想知道这是否是操作系统限制?还是有什么不对的地方?

【问题讨论】:

标签: android listview caching android-listview android-asynctask


【解决方案1】:

此警告意味着您的代码占用了大量处理时间/内存,因此 Android 会大致跳过几个计算(帧)。您正在做的事情可能会阻止旧智能手机执行您的代码。对于解决方案,您应该使用 Arju 已经说明的 AsynTasks 移动 UI 线程的关键部分。一个很好的介绍可以找到here (Displaying Bitmaps Efficiently)。特别是当您声明您当前正在渲染“未压缩的真实相机捕获的图像”时,您应该仔细阅读Loading Large Bitmaps Efficiently 部分。在那里你会看到这些图像的实际内存分配比你想象的要大得多。最后但同样重要的是,如果您仍然面临性能问题,请阅读 Making ListView Scrolling Smooth

我主张在使用 LazyList 或 Android Universal Image Loader 等 3rd 方库之前熟悉这些问题。

【讨论】:

  • 您好,感谢您的建议,但请参阅我提到的我已经使用 AsyncTask 的帖子。我已经验证了每个“获取”位图的时间大约为 10 毫秒,并且由于它处于异步状态,因此看起来不像是滞后的问题。
  • 对不起。我的失败。但是,为什么要将 AsyncTask 作为 Singleton 应用?这不是表示图像的顺序加载而不是并行处理吗?通常,您会对要填充的 ImageView 持有弱引用,并且在开始新的 AsyncTask 之前,您会检查是否已经有一个适用于该 ImageView (Handle Concurrency)。我不确定这是否也适用于 ViewHolder。 ://
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
相关资源
最近更新 更多