我目前正在从服务器下载471个缩略图,将尺寸加倍,将其保存在设备上,并使用带有自定义图像字段的TableLayoutManager来显示它们。但是,我认为创建这些额外的471自定义图像字段会导致巨大的内存泄漏。
我在下载时监视内存使用情况,在垃圾收集器启动之前它只缓慢增加到大约10-18 mb,所以很好。但是,一旦所有缩略图都缓存在手机上,它就会使用100+兆字节从磁盘读取图像,大小加倍,创建471自定义图像字段并显示它们。 471缩略图的总大小为427 kb。系统如何使用那么多内存来加载这些文件?
但是,如果我能够使用像tablelayoutmanager这样的列表字段,那么我就不必创建那些额外的471自定义图像字段,只需将图像直接添加到列表字段中。
有没有人必须做类似的事情,或者有一个关于如何使用listfield实现格式表的示例?
答案 0 :(得分:2)
427kb是PNG图像的下载大小。 PNG是压缩的。当你在内存中打开它们时它们会实际扩展,这样图像中的每个像素都可以包含最多4个字节(ARGB)值(取决于格式)以及其他PNG元数据。
使用两倍大小(尺寸)保存缩略图不一定会产生双倍大小的文件大小。它可能更大或更小,具体取决于图像和图像压缩器的好坏。
将图像直接添加到列表字段不会有任何区别。你仍然会将它们加载到内存中。你需要做的是在内存缓存中有一些可管理的最多20个图像。您的代码需要足够聪明,以便随时检测用户在列表字段中的位置,并显示该视图的图像。
因此,假设每个列表字段对象(或行)具有与相应图像(例如文件名)相关联的标记。用户完成向上/向下滚动后,您可以加载该视图的图像。如果列表字段中显示的第一行是第20行,并且您可以显示8个项目,则需要获取图像20 - 28并将其加载到内存缓存中(如果它们尚不存在)(因此请先检查缓存) )。然后在列表字段上调用invalidate()以确保重新绘制。
线程:
a)您不需要线程来检测用户在任何位置。您应该能够使用moveFocus方法或导航方法,并确定用户的位置。
b)对于加载图像,您需要一个排队机制。一旦你了解了线程/锁定机制,任务队列就很容易实现。队列中的每个任务都会将图像加载到自己的线程中。您需要一次设置队列中有多少任务(线程)处于活动状态的限制。我最多可以选择3-5个(这是来自BB平台的经验)。对于队列实现,我建议通过阅读有关任务/作业队列和生产者/消费者问题。
以上机制使用了很多。这就是为什么当您向下滚动联系人列表时,您可能会在联系人图像被加载并在联系人姓名旁边呈现之前看到稍微延迟。