You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Android如何在Dialog dismiss时清除引用解决内存泄漏问题

解答

核心问题根因

1. Dialog重复创建导致内存溢出

你将Dialog.Show()、Adapter创建、ListView赋值逻辑写在了for循环内部,有多少条天体数据就会弹出多少个重叠的AlertDialog,每个Dialog都会持有dialogView、图片资源、列表控件的引用,直接导致内存占用短时间内飙升,触发OOM崩溃。你观察到的崩溃出现在无关代码行,是因为内存耗尽时系统强制杀掉应用,恰好当时执行到该行代码,和该行代码本身无关。

2. 资源释放逻辑错误

Xamarin.Android会自动管理Java层对象的生命周期,你在监听中手动调用Dispose释放Dialog和View,反而可能导致野指针问题,增加崩溃概率。

修复方案

调整代码逻辑,把列表数据处理、Adapter创建、Dialog显示的逻辑移到for循环外部:

// 仅保留数据处理逻辑在循环内
for (int i = 0; i < currentObjects.Count(); i++)
{
    var secondG = GetItemPosition(planets, currentObjects[i].name);
    var gPercentage = Math.Round(gInfo.PercentageGravity(firstCelestialLoc, secondG), 0);

    switch (gInfo.ComparedGravity(firstCelestialLoc, secondG))
    {
        case 0:
            gravType = GetString(Resource.String.gravLower);
            currentObjects[i].color = "#43A047";
            break;
        default:
            gravType = GetString(Resource.String.gravGreater);
            currentObjects[i].color = "#F44336";
            break;
    }

    var gravVal = SpinnerGravityUnits.Text == gUnits[0] ? gInfo.GetGravity(secondG) : Math.Round(gravity.ChangeToFeet(gInfo.GetGravity(secondG)), 3);

    currentObjects[i].name = $"<b>{currentObjects[i].name}, {GetCelestialObject(gInfo.CelestialObjectType(secondG))}</b><br>{gravVal} {SpinnerGravityUnits.Text}, {string.Format(gravType, gPercentage)}";

    if (isNumeric && earthWeight > 0)
    {
        currentObjects[i].name += $"<br>{GetString(Resource.String.lblYourWeightCO)} {GetNewWeight(gPlanets, double.Parse(TxtWeight.Text), firstCelestialLoc, secondG)} {SpinnerWeightUnits.Text}";
    }
}

// 循环结束后再初始化Adapter、显示Dialog
var adapter = new CompareAllAdapter(currentObjects);
listView.Adapter = adapter;
Dialog.SetView(dialogView);
Dialog.SetOnDismissListener(new OnDismissListener());
Dialog.Show();

额外优化建议

  1. 去掉手动Dispose Dialog和View的逻辑,只需要在Dialog关闭后清空类层面持有的Dialog、dialogView引用即可。
  2. 若Dialog中使用的图片资源较大,可以在Dialog关闭时主动回收ImageView的Drawable资源,进一步降低内存占用。
  3. 列表TextView展示HTML内容时,使用Html.FromHtml方法处理,避免字符串拼接带来的性能损耗。

内容的提问来源于stack exchange,提问作者Federico Navarrete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 09:36:03