Android 安卓GRef在设置视图标签时增加

Android 安卓GRef在设置视图标签时增加,android,memory,reference,Android,Memory,Reference,我正在处理一个日历活动,并实现了一个用于处理数据的适配器。一个月的每一天我都有一个按钮,我为它设置了一个标签。然后,当按下按钮时,我可以从标签上分辨出它的日期。可以跳到下一个月/上一个月,从而更改日历视图的数据。然而,我的问题是,每次我设置按钮的标签时(当视图被重用时),GRef都会增加,并且永远不会释放,当它达到2000时,应用程序会自动关闭。当取消注释设置标记的代码行时,Gref不会增加,应用程序也不会更改。 以下方法来自我的适配器: private int key = Resource.

我正在处理一个日历活动,并实现了一个用于处理数据的适配器。一个月的每一天我都有一个按钮,我为它设置了一个标签。然后,当按下按钮时,我可以从标签上分辨出它的日期。可以跳到下一个月/上一个月,从而更改日历视图的数据。然而,我的问题是,每次我设置按钮的标签时(当视图被重用时),GRef都会增加,并且永远不会释放,当它达到2000时,应用程序会自动关闭。当取消注释设置标记的代码行时,Gref不会增加,应用程序也不会更改。 以下方法来自我的适配器:

 private int key = Resource.Id.string_key;     
public override View GetView(int position, View convertView, ViewGroup parent)
            {
                View row = convertView;
                if (row == null)
                {
                    LayoutInflater inflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService);
                    row = inflater.Inflate(Resource.Layout.calendar_grid_cell, parent, false);
                }

                // Get a reference to the Day gridcell
                gridcell = (Button)row.FindViewById(Resource.Id.calendar_day_gridcell);
                gridcell.SetOnClickListener(this);
                string[] words = list[position].Split(delimiterChars);
                gridcell.Text = words[2];
                gridcell.SetTag(key, words[1]);

                return row;
            }

有人对我能做什么有建议吗?在设置新标记之前,我已尝试将标记属性设置为null,或者我应该避免使用标记并找到其他方法吗?

这里的问题有两个:

  • 你在打电话

  • 存在从的隐式转换

  • 因此:

    gridcell.SetTag(key, words[1])
    
    在道德上等同于:

    Java.Lang.Object tmp = words[1];
    gridcell.SetTag(key, tmp);
    
    这会导致gref被消费,而且它可能永远不会被收集,因为Android保留了Dalvik端的
    java.lang.String
    实例,这意味着Android GC的Mono会认为
    tmp
    实例无法被收集

    幸运的是,我们知道得更多,并且能够相应地行动。将代码更改为:

    using (var tag = new Java.Lang.String(words[1]))
        gridcell.SetTag(key, tag);
    
    这将
    Dispose()

    注意:您必须在

    这就是事情的最初一面。查找方面是相同的,但不同:

    using (var tag = new Java.Lang.String("some-tag")) {
        var gridcell = row.FindViewWithTag(tag).JavaCast<Button>();
        // use gridcell...
    }
    
    private int key = Resource.Id.string_key;     
    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        if (row == null) {
            LayoutInflater inflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService);
            row = inflater.Inflate(Resource.Layout.calendar_grid_cell, parent, false);
        }
    
        // Get a reference to the Day gridcell
        using (var gridcell = row.FindViewById<Button>(Resource.Id.calendar_day_gridcell)) {
            gridcell.SetOnClickListener(this);
            string[] words = list[position].Split(delimiterChars);
            gridcell.Text = words[2];
            using (var tag = new Java.Lang.String(words[1]))
                gridcell.SetTag(key, tag);
        }
    
        return row;
    }