当使用ViewHolder模式时,调用Dispose()的正确时机是什么?



我使用了James Montemagno所描述的ViewHolder模式

https://blog.xamarin.com/creating-highly-performant-smooth-scrolling-android-listviews/

考虑到FindViewById调用的对象,我应该何时调用dispose?什么是安全和正确的做法。我应该找个时间来做https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/

要缩短对象生命周期,应该调用Java.Lang.Object.Dispose()。这将手动"切断"对象上的连接两个虚拟机通过释放全局引用,从而允许对象

ListView相当老(Android 1.0)。它是紧密耦合的,构建时没有考虑到性能。为了保持它的相关性,需要大量的黑客攻击。RecyclerView填补了这个空白。

https://www.youtube.com/watch?v=LqBlYJTfLP4

至于何时应该调用Dispose(), RecyclerView应该通过LayoutManager来处理这个基本功能。在ViewHolder端,您可以遵循基本的Dispose模式:

protected override void Dispose (bool disposing)
    {
        base.Dispose (disposing);
        if(ItemView != null)
        {
            ItemView.Click -= HandleClick;
        }
        _listener = null; //Listener might just be a simple Action<int> like in this example: https://github.com/xamarin/monodroid-samples/blob/master/android5.0/RecyclerViewer/RecyclerViewer/MainActivity.cs#L111
    }

您只关心处置基类和您设置的任何事件处理程序。然而,如果你的RecyclerViewView中使用了一些图像,你将需要确保你正确管理这些资源,因为Android GC将无法收集这些项目,因为它们将被Xamarin引用。Android的GC(它们将是一个小的参考,比如几个字节值)。你必须以某种方式切断两个gc之间的连接,这样它才有资格被收集。你可以在这里阅读更多关于垃圾收集算法:Xamarin Android垃圾收集算法和原因在这里:https://developer.xamarin.com/guides/cross-platform/deployment,_testing,_and_metrics/memory_perf_best_practices/#Use_Weak_References_to_Prevent_Immortal_Objects

要做到这一点,我们可以通过以下几种方式切断关系:

  1. MyObject = null;
  2. MyObject.Dispose();

无论哪种方式都应该标记这些项目符合GC的条件。在Drawable的情况下,您可能还希望将Drawable正在设置的ImageView或对象设置为null,例如SetBackgroundDrawable/等。

TLDR;使用RecyclerView,并记住适当地管理Bitmap/Drawable资源。

最新更新