Skip to content

Commit d23709b

Browse files
committed
added CollectionView fix for children leak
1 parent 7ab3336 commit d23709b

File tree

13 files changed

+708
-450
lines changed

13 files changed

+708
-450
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
using Android.App;
7+
using Android.Content;
8+
using Android.OS;
9+
using Android.Runtime;
10+
using Android.Views;
11+
using Android.Widget;
12+
13+
using ShadowsSample.Droid;
14+
15+
using Sharpnado.Presentation.Forms.Droid.Helpers;
16+
using Sharpnado.Shades.Droid;
17+
18+
using Xamarin.Forms;
19+
using Xamarin.Forms.Platform.Android;
20+
21+
[assembly: ExportRenderer(typeof(CollectionView), typeof(CollectionViewLeakRenderer))]
22+
23+
namespace ShadowsSample.Droid
24+
{
25+
public class CollectionViewLeakRenderer : CollectionViewRenderer
26+
{
27+
public CollectionViewLeakRenderer(Context context)
28+
: base(context)
29+
{
30+
}
31+
32+
protected override void Dispose(bool disposing)
33+
{
34+
System.Diagnostics.Debug.WriteLine(ItemsViewAdapter);
35+
36+
if (!disposing)
37+
{
38+
base.Dispose(false);
39+
return;
40+
}
41+
42+
var children = GetChildren();
43+
base.Dispose(true);
44+
DisposeChildren(children);
45+
}
46+
47+
private ItemContentView[] GetChildren()
48+
{
49+
System.Diagnostics.Debug.WriteLine($"GetChildren() => count: {ChildCount}");
50+
var result = new ItemContentView[ChildCount];
51+
for (int childCount = ChildCount, i = 0; i < childCount; ++i)
52+
{
53+
result[i] = (ItemContentView)GetChildAt(i);
54+
}
55+
56+
return result;
57+
}
58+
59+
private void DisposeChildren(ItemContentView[] children)
60+
{
61+
System.Diagnostics.Debug.WriteLine($"DisposeChildren() => count: {children.Length}");
62+
for (int childCount = children.Length, i = 0; i < childCount; ++i)
63+
{
64+
var itemContentView = children[i];
65+
if (!itemContentView.IsNullOrDisposed())
66+
{
67+
// System.Diagnostics.Debug.WriteLine(itemContentView.DumpHierarchy(true));
68+
var view = itemContentView.GetChildAt(0);
69+
if (!view.IsNullOrDisposed())
70+
{
71+
view.Dispose();
72+
}
73+
74+
itemContentView.RemoveAllViews();
75+
itemContentView.Dispose();
76+
}
77+
}
78+
}
79+
}
80+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
using Android.App;
7+
using Android.Content;
8+
using Android.OS;
9+
using Android.Runtime;
10+
using Android.Views;
11+
using Android.Widget;
12+
13+
using Square.LeakCanary;
14+
15+
namespace ShadowsSample.Droid
16+
{
17+
[Application]
18+
internal class MainApplication : Application
19+
{
20+
private RefWatcher _refWatcher;
21+
22+
protected MainApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
23+
{
24+
}
25+
26+
public override void OnCreate()
27+
{
28+
base.OnCreate();
29+
SetupLeakCanary();
30+
}
31+
32+
protected void SetupLeakCanary()
33+
{
34+
if (LeakCanaryXamarin.IsInAnalyzerProcess(this))
35+
{
36+
// This process is dedicated to LeakCanary for heap analysis.
37+
// You should not init your app in this process.
38+
return;
39+
}
40+
_refWatcher = LeakCanaryXamarin.Install(this);
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)