格列夫的Android设置的角度标记时增加 [英] Android GRef increase when setting tag of view
问题描述
我与日历活动工作,并已实施了处理数据的适配器。对于每天都在一个月我有一个按钮,我设置的标签。然后,当按钮被按下我可以告诉它是从标签的日期。它可以跳到下一个/上个月从而改变数据的日历视图。但是我的问题是,每次我设置按钮的标签(如视图重复使用)的格列夫增加,从来没有公布过,当它击中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?
推荐答案
这里的问题是双重的:
有来自字符串的隐式转换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;
}
这篇关于格列夫的Android设置的角度标记时增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!