我一直在阅读很多关于图像加载器,位图和asynctaks的帖子,以便下载和显示图像。在处理少量位图时,我的图像加载器很好,它会下载图像并将其显示给用户,但它也将WeakReference保存在HashMap中,我将其用作缓存并将图像保存在SD卡中如果用户需要稍后显示该图像而无需再次下载。到目前为止,这很好,我的应用程序工作正常。
现在我开始研究一个新的应用程序,在同一个屏幕上显示的图像数量大于50(例如),在这种情况下屏幕不能平滑滚动,我也发现FPS低于平常,提供糟糕的用户体验。我对下一步该做什么的想法不足。有没有人有建议?
使用WeakReference而不是WeakReference可以改善内存使用情况以及用户体验?
我下载它们时没有缩放位图,因为它们已经是缩略图,我应该缩放它们吗?图像最多可占据屏幕宽度的50%。
现在我的主要关注点与下载时间无关,我关心的是显示的位图数量以及滚动的平滑程度。我没有使用gridview,我正在使用http://code.google.com/p/android-masonry
中的砌体组件你们对我有什么样的建议?我应该从哪里开始看?
由于 蒂亚戈
答案 0 :(得分:0)
您是否在应用上使用了DDMS?你是垃圾收集中的应用程序吗?
您只有有限的内存,并且难以管理位图。您在评论中提到缓存不是问题,但如果内存不足,则不希望再保留比您需要的位图更多的位图。您可能一次只能绘制50个左右的图像,但您的缓存可能会保留100个位图并占用内存。我不会依靠WeakReference为您解决问题,尤其是使用Bitmaps。您是否粗略估计了50张图像消耗的内存量?
我与此相关的经验是构建自定义地图应用程序,该应用程序必须显示许多256x256的地图图块。所以我经历了你现在经历的大部分事情。您确实需要某种形式的缓存来保持UI响应,因此用户不会在网络上等待图像。但是在尝试了硬缓存,然后是软缓存,甚至是动态缓存(硬内存缓存和软内存缓存的组合)之后,我终于决定只缓存需要的东西并扔掉其余部分。因此,我计算内存中的任何当前图像是否在下一个矩形中有效(比如用户正在骂),如果是,我重用它们,如果不是我扔掉它们 - 这是我保留的唯一内存缓存。我需要从网络下载的图像被写入SD卡并仅在需要时被拉入内存。
要看的另一件事是BitmapFactory.Options.inPreferredConfig。如果可以,请尝试在RGB_555处拉入所有图像。默认值为ARGB_8888,其大小是RGB_555的两倍。
最后确保位图是问题所在。使用DDMS。通常看起来曾经是一个非常简单的困难问题 - 它总是被忽视的简单的东西,让你在深夜。
答案 1 :(得分:0)
在Android培训上查看这个新课程:Displaying Bitmaps Efficiently。它讨论了许多与您的问题相关的内容,例如内存使用,图像缩放,平滑滚动(仅适用于ListView和GridView等组件)以及使用内存和磁盘缓存来提高性能。特别是,本节(来自Caching Bitmaps):
注意:过去,流行的内存缓存实现是SoftReference或WeakReference位图缓存,但不建议这样做。从Android 2.3(API级别9)开始,垃圾收集器更积极地收集软/弱引用,这使得它们相当无效。此外,在Android 3.0(API Level 11)之前,位图的后备数据存储在本机内存中,而该内存未以可预测的方式发布,可能导致应用程序短暂超出其内存限制并崩溃。
正如在另一个答案中所提到的,相反,使用像LruCache类这样的东西来优先选择强引用的缓存。