diff --git a/src/Core/src/Platform/Android/MauiWindowInsetListener.cs b/src/Core/src/Platform/Android/MauiWindowInsetListener.cs
index 3e1d2509d4c5..97f4c9e9de19 100644
--- a/src/Core/src/Platform/Android/MauiWindowInsetListener.cs
+++ b/src/Core/src/Platform/Android/MauiWindowInsetListener.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.CompilerServices;
using Android.Content;
using Android.Views;
using AndroidX.Core.Graphics;
@@ -12,11 +13,6 @@
namespace Microsoft.Maui.Platform
{
- ///
- /// Registry entry for tracking view instances and their associated listeners.
- /// Uses WeakReference to avoid memory leaks when views are disposed.
- ///
- internal record ViewEntry(WeakReference View, MauiWindowInsetListener Listener);
///
/// Manages window insets and safe area handling for Android views.
@@ -36,8 +32,9 @@ internal class MauiWindowInsetListener : WindowInsetsAnimationCompat.Callback, I
// Static tracking for views that have local inset listeners.
// This registry allows child views to find their appropriate listener without
// relying on a global activity-level listener.
+ // Uses ConditionalWeakTable for O(1) lookup and automatic cleanup.
// Thread Safety: All access must be on UI thread (enforced by Android's threading model).
- static readonly List _registeredViews = new();
+ static readonly ConditionalWeakTable _registeredViews = new();
///
/// Registers a view to use this local listener instead of the global one.
@@ -47,23 +44,7 @@ internal class MauiWindowInsetListener : WindowInsetsAnimationCompat.Callback, I
/// The view to register
internal void RegisterView(AView view)
{
- // Clean up dead references and check for existing registration
- for (int i = _registeredViews.Count - 1; i >= 0; i--)
- {
- var entry = _registeredViews[i];
- if (!entry.View.TryGetTarget(out var existingView))
- {
- _registeredViews.RemoveAt(i);
- }
- else if (existingView == view)
- {
- // Already registered, no need to add again
- return;
- }
- }
-
- // Add this view to the registry
- _registeredViews.Add(new ViewEntry(new WeakReference(view), this));
+ _registeredViews.AddOrUpdate(view, this);
}
///
@@ -73,14 +54,10 @@ internal void RegisterView(AView view)
/// The view to unregister
internal static MauiWindowInsetListener? UnregisterView(AView view)
{
- for (int i = _registeredViews.Count - 1; i >= 0; i--)
+ if (_registeredViews.TryGetValue(view, out var listener))
{
- if (_registeredViews[i].View.TryGetTarget(out var registeredView) && registeredView == view)
- {
- var listener = _registeredViews[i].Listener;
- _registeredViews.RemoveAt(i);
- return listener;
- }
+ _registeredViews.Remove(view);
+ return listener;
}
return null;
}
@@ -107,22 +84,9 @@ internal void RegisterView(AView view)
return null;
}
- if (parent is AView parentView)
+ if (parent is AView parentView && _registeredViews.TryGetValue(parentView, out var listener))
{
- // Check if this parent view is registered
- // Clean up dead references while searching
- for (int i = _registeredViews.Count - 1; i >= 0; i--)
- {
- var entry = _registeredViews[i];
- if (!entry.View.TryGetTarget(out var registeredView))
- {
- _registeredViews.RemoveAt(i);
- }
- else if (ReferenceEquals(registeredView, parentView))
- {
- return entry.Listener;
- }
- }
+ return listener;
}
parent = parent.Parent;