使用MVVM Cross重新采样Android中列表的大位图

时间:2015-06-19 10:18:49

标签: image-processing memory-management xamarin xamarin.android mvvmcross

我有一长串单元格,每个单元格都包含一个图像。

图像在磁盘上很大,因为它们用于应用程序中的其他内容,如壁纸等。

我熟悉正常的Android流程,用于重新采样大型位图并在不再需要时处理它们。

但是,我觉得尝试在列表适配器中动态重新采样图像将是低效的,而不会在解码后缓存它们,否则会产生许多线程,我将不得不管理取消不需要的图像等等。

该应用程序的构建广泛使用了梦幻般的MVVMCross框架。我正在考虑使用MvxImageViews,因为它们可以从磁盘加载图像并轻松缓存它们。问题是,我需要在缓存它们之前对它们进行重新采样。

我的问题是,有没有人知道在MVVMCross中这样做的既定模式,或者对如何实现它有任何建议?我是否需要自定义下载缓存插件?任何建议都会很棒:)

1 个答案:

答案 0 :(得分:2)

好的,我想我找到了答案。我一直在意外地看着旧的MVVMCross 3.1版本的DownloadCache插件/ MvxLocalFileImageLoader。

克隆最新版(v3.5)回购后,我发现已添加此功能。现在缓存本地文件,并且可以在首次加载时重新采样:)

MvxImageView有一个Max Height / Width setter方法,它传播到它的MvxImageHelper,后者又将它发送到MvxLocalFileImageLoader。

需要注意的一点是,只有在从文件加载时才会重新采样,而不是在使用资源ID时。

来源在这里:https://github.com/MvvmCross/MvvmCross/blob/3.5/Plugins/Cirrious/DownloadCache/Cirrious.MvvmCross.Plugins.DownloadCache.Droid/MvxAndroidLocalFileImageLoader.cs

MVVMCross再一次节省了我的一天^ _ ^

更新: 现在我实际上已经完成了所有工作,这里有一些指示:

  • 正如我在评论中所指出的,本地图像缓存目前仅在3.5.2 alpha MVVMCross上可用。这与我的项目不兼容,因此使用3.5.1我创建了我自己的3.5.2a MvxImageView,MvxImageHelper和MvxAndroidLocalFileImageLoader的副本及其接口,并在Setup类中注册它们。

  • 我修改了MvxAndroidLocalFileImageLoader以重新取样资源,而不仅仅是文件。

  • 您必须使用" res:"绑定到MvxImageView的ImageUrl属性。这里记录的前缀(Struggling to bind local images in an MvxImageView with MvvmCross);如果你绑定到' DrawableId'这会将图像直接分配给基础ImageView,并且不会发生缓存/重新采样。

  • 我需要能够设置自定义的MvxImageview的最大高度/宽度,以便在布局被充气/绑定后重新取样,但之前检索图像(我想在“OnMeasure'”期间设置它们,但是图像已经被加载了)。可能有一个更好的方法,但我在一个bool旗帜' SizeSet'。如果这是假的(即在初始绑定期间),则临时存储图像URL。一旦将其设置为true(在OnMeasure之后),存储的url将传递给要加载的基础ImageHelper。

  • 该应用的一部分使用全屏图像作为寻呼机适配器中片段的背景。位图没有足够快地收集垃圾,导致在尝试加载下一个大图像时最终的OOM。在销毁片段时手动调用GC.Collect()会释放内存,但会导致UI口吃,并在使用弱引用时擦除缓存。

  • 当在寻呼机适配器中的片段之间移动时,我在Lollipop上频繁发生SIGSEGV崩溃(它们从未发生在KitKat上)。我设法通过向ImageView的Dispose方法添加SetImageBitmap(null)来解决这个问题。然后我在其包含片段的OnDestroyView()上的ImageView上调用Dispose()。

希望这对某人有所帮助,因为它花了我一段时间!