格列夫的Andr​​oid设置的角度标记时增加 [英] Android GRef increase when setting tag of view

查看:113
本文介绍了格列夫的Andr​​oid设置的角度标记时增加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与日历活动工作,并已实施了处理数据的适配器。对于每天都在一个月我有一个按钮,我设置的标签。然后,当按钮被按下我可以告诉它是从标签的日期。它可以跳到下一个/上个月从而改变数据的日历视图。但是我的问题是,每次我设置按钮的标签(如视图重复使用)的格列夫增加,从来没有公布过,当它击中2000应用程序chrashes。如果在取消code设置标签格列夫没有增加,应用程序并不chrash线。
下面的方法是从我的适配器:

I am working with a calendar activity and have implemented an adapter for handling the data. For every day in a month I have a button for which I set a tag. Then when the button is pushed I can tell which date it is from the tag. It is possible to skip to next/last month and thereby changing the data for the calendar view. However my problem is that every time i set the tag of the button(as the views are reused) the GRef is increased and never released and when it hits 2000 the app chrashes. When uncommenting the line of code setting the tag the Gref is not increased and the app does not chrash. The following method is from my adapter:

 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;
            }

不要任何人有什么我可以做一个建议?我曾尝试设置新的标签也即之前设置标签属性为空或者我应该避免使用标签,找到一些其他的方式?

Do anyone have a suggestion for what I can do? I have tried setting the tag property to null before setting the new tag- Or Should I just avoid using tags and find some other way?

推荐答案

这里的问题是双重的:


  1. 您所呼叫 View.SetTag(INT, java.lang.Object)中的

有来自字符串的隐式转换java.lang.Object继承

所以这个:

gridcell.SetTag(key, words[1])

在道德上是等价的:

is morally the equivalent of:

Java.Lang.Object tmp = words[1];
gridcell.SetTag(key, tmp);

这导致格列夫被消耗,并且很可能永远不会被收集,因为Android是抱着到的Dalvik端 java.lang.String中例如,这意味着单声道为Android的GC会认为 TMP 实例不能被收集。

This causes a gref to be consumed, and it likely won't ever be collected, because Android is holding onto the Dalvik-side java.lang.String instance, which means Mono for Android's GC will believe that the tmp instance cannot be collected.

幸运的是,的 <我们/ em>的更清楚,并能相应的行为。更改code为:

Fortunately, we know better, and can behave accordingly. Change your code to:

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

这将的Dispose()包装的实例,这是很好的(在这种情况下!的),因为我们并不需要它,我们的知道的我们并不需要它。

This will Dispose() of the wrapper instance, which is fine (in this case!) because we don't need it, and we know we don't need it.

注意:你必须是<一个href=\"http://docs.xamarin.com/Android/Guides/Advanced_Topics/Architecture#$p$pmature_Dispose%28%29_Calls\"相对=nofollow>非常小心,当 利用的东西你知道

这就是事物的初始化的一面。事物的查找侧是相同的,但是,不同的:

So that's the init side of things. The lookup side of things is the same-but-different:

using (var tag = new Java.Lang.String("some-tag")) {
    var gridcell = row.FindViewWithTag(tag).JavaCast<Button>();
    // use gridcell...
}

这工作,因为<一href=\"http://developer.android.com/reference/android/view/View.html#findViewWithTag%28java.lang.Object%29\"相对=nofollow> 记录为使用View.findViewWithTag()是Object.equals(),而不是引用平等,因为我们在这里使用字符串我们使用 String.equals(),其执行价值相等。

This works because View.findViewWithTag() is documented as using Object.equals() and not reference equality, and since we're using strings here we're using String.equals(), which performs value equality.

如果grefs是一个主要问题,你可以走一步与栅格单元格列夫处置,的除非栅格单元可能是C#子类。 (的这种需要访问你的 .axml

If grefs are a major concern, you could go one step further and dispose of the gridcell gref, unless gridcell could be a C# subclass. (Knowing this requires access to your .axml.)

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;
}

这篇关于格列夫的Andr​​oid设置的角度标记时增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆