2013-12-16 163 views
1

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

这里的细节:

在ListView中,我有一个ViewHolder保持所有项目实例,这样它会比做findViewById更快。在此列表视图的活动加载时,我将旋转一些图像加载器AsyncTasks来帮助加载图像。我的图像加载器是作为单例实现的,并且具有两级缓存。所述第一级高速缓存是一个SoftReferenceMap

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

和L2高速缓存是一个缓存文件夹。如果缓存无法访问,代码将执行异步下载并更新视图。整个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,图像视图变得非常平滑。

我想知道这是否是操作系统限制?或者有什么是错的?

+3

使用asynctask加载位图 –

+0

尝试使用通用图像加载器https://github.com/nostra13/Android-Universal-Image-Loader – SathishKumar

+0

你可以在将图像添加到列表视图之前缩放图像? –

回答

1

此警告意味着您的代码需要很多处理时间/内存,因此Android会跳过粗略地说说几个计算(框架)。你在做什么可能会阻止较旧的智能手机执行你的代码。对于解决方案,您应该使用AsynTasks移动UI线程的关键部分,正如Arju所述。一个很好的介绍可以找到here (Displaying Bitmaps Efficiently)。尤其是当您声明您目前正在渲染“未压缩的真实相机拍摄的图像”时,您应该仔细阅读部分Loading Large Bitmaps Efficiently。在那里你会看到,这样的图像的实际内存分配比你想象的要大得多。最后但并非最不重要的,如果你仍然面临性能问题,请阅读Making ListView Scrolling Smooth

在使用第三方库如LazyList或Android通用图像加载器之前,我会主张熟悉这些问题。

+0

嗨,谢谢你的建议,但请参考我的帖子,我提到我已经使用AsyncTask。我已经验证了“获取”位图的时间是每个10毫秒,并且由于它处于异步状态,因此它看起来不像是滞后问题。 –

+1

对不起。我的失败。但是,为什么您将AsyncTask作为Singleton应用?这是不是表示图像的顺序加载而不是并行处理?通常情况下,你会持有对你想要填充的ImageView的弱引用,并且在开始一个新的AsyncTask之前,你会检查是否已经有一个用于这个ImageView([Handle Concurrency])(http://developer.android.com/training/显示的位图/过程bitmap.html#并发))。我不确定这是否也适用于ViewHolder。 :/ – Baschi