当前位置 : 主页 > 网页制作 > xml >

xml – 当我将MvxBindableSpinner放入MvxBindableListView时,为什么gref会变得太高?

来源:互联网 收集:自由互联 发布时间:2021-06-13
我正在使用mvvmcross为 Android开发应用程序. 在这个应用程序中,我想有一个包含微调器的列表.当我在模拟器上测试应用程序时它看起来不错,但是当我滚动它时内存很快因为gref超过2000.我知
我正在使用mvvmcross为 Android开发应用程序.

在这个应用程序中,我想有一个包含微调器的列表.当我在模拟器上测试应用程序时它看起来不错,但是当我滚动它时内存很快因为gref超过2000.我知道gref可以在真实设备上更高但我仍然认为我必须做错了.

BindableList

<cirrious.mvvmcross.binding.android.views.MvxBindableListView
          android:id="@+id/propertyHolder"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:layout_below="@id/obsBtLayout"
          android:layout_above="@id/photoframe"          
          local:MvxBind="
          {
            'ItemsSource':{'Path':'PPHolders'},
            'ItemClick':{'Path':'PropertyClickedCommand'}
          }"
          local:MvxItemTemplate="@layout/listitem_property"
        />

ListItem_Property.axml(剥离)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"              
  xmlns:local="http://schemas.android.com/apk/res/AIPApp.UI.Droid"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="@drawable/ListItemSelector"           
  android:descendantFocusability="beforeDescendants"
  >

  <cirrious.mvvmcross.binding.android.views.MvxBindableSpinner
    android:layout_gravity="center_horizontal"
    android:layout_width="200dip"
    android:layout_height="wrap_content"    
    local:MvxDropDownItemTemplate="@layout/spinneritem_propdropdown"
    local:MvxItemTemplate="@layout/spinneritem_prop"
    local:MvxBind="
    {
      'ItemsSource':{'Path':'CodeTableValues'},      
      'SelectedItem':{'Path':'ObservedCodeTable'},
      'Visibility':{'Path':'IsCodeTableValue','Converter':'Visibility'}
    }"/>     

</LinearLayout>

这是否发生是因为每次滚动时都必须重建微调器项目?因为它所绑定的列表在列表中的每个项目中都是不同的.因此,在一个列表项上,微调器列表可以是六个项目,另一个可以是3个项目,依此类推.

我还没有对你所看到的行为进行全面分析 – 如果没有完整的代码示例则很难做到.

但是,特别感谢JonPryor在Xamarin forums上我相信我现在至少能够更好地理解GREF在一般情况下发生的事情 – 所以我可以回答你的“为什么”问题.

绑定列表的一般情况是GREF递增:

>每次绑定一次 – 因为绑定存储在混合C#/ Java容器对象中 – https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/MvxJavaContainer.cs
>每个ListView项目一次 – 因为它在列表中使用
>对于ListView中具有绑定属性或事件的每个View对象,一次 – 例如如果绑定到每个ListView项目中的TextView和Button,则C#将存储对这些视图的引用

在您的示例中,每个列表项本身都包含一个绑定列表 – 这将导致所需的GREF数量的倍增 – 这就是您看到报告的问题的原因.

有了这种理解,显而易见的问题可能是“我们如何解决这个问题?”

这不是一个简单的问题,但我认为有一些方法可以解决这个问题.

首先,我们可以与Xamarin讨论这个问题 – 可能是应该增加可用的GREF数量 – 因为这些对象将在Java内存中,那么在C#中引用它们也许没有坏处?

其次,我们可以考虑改变实现UI绑定的方式,以便永久引用不会存储到所有对象 – 例如,如果我们知道一次性绑定(例如,对于标签),那么我们可能会看一条路线不对此功能使用XML数据绑定.例如,我们可以使用新的View手动执行此绑定.

第三,我们可以考虑更改绑定代码本身,以便对于单向绑定(从ViewModel到View),它使用FindViewById< TView>检索Android视图.在更新时,而不是使用保留的视图引用.这会更慢,但会减少所需的GREF数量.在明确声明的“一次性”绑定的情况下,此功能可能是最可实现的.

第四,这是作为应用程序开发人员最容易访问的解决方案,您可以查看更改UI实现,以便应用程序不使用这些绑定的子列表 – 例如它可以改为使用标签 – 它只按需创建微调器(通过处理代码中的Click事件).

我相信除此之外还有其他选择……

在此分析中我问自己的一个问题是,这个问题是否是MvvmCross独有的,或者是否是一个可能在所有MonoDroid应用程序中看到的问题.

我不是百分百肯定,但我认为答案是这是一个影响所有MonoDroid应用程序的一般性问题.但是,我也认为MvvmCross在这个问题上增加了一点:

>通过持有TextViews / labels之类的引用
>通过使您更容易编写引用大量Java对象的代码.

我也不认为这完全只是一个MvvmCross或MonoDroid问题.虽然由于MonoDroid的实现而突出了这个GREF限制,但这里的根本问题实际上是尝试一次做太多 – 所以你真的可以通过对设计/实现进行流式处理来提高应用程序的性能,以便减少使用观点.虽然它可能不喜欢它,但我认为MonoDroid在这方面对我们有利 – 它指出我们的UI实现有点“胖”,我们应该考虑在我们的应用程序代码中优化它.

我会在发现更多信息后更新这个答案,但我希望上述信息已经让您对这种情况的“原因”有了很好的了解.

网友评论