Skip to content

Commit 47ce547

Browse files
authored
Fix Material Slider ACW implementor build failure (#1484) (#1486)
Remove the restricted BaseOnChangeListener/BaseOnSliderTouchListener base interfaces and break the C# implements chain on the typed sub-interfaces to avoid the ACW type-erasure clash. Re-add typed AddOn*/RemoveOn* listener methods via Additions so the public API uses Slider.IOnChangeListener and RangeSlider.IOnChangeListener as recommended by Android. Bump nugetVersion to 1.14.0.4. ### Move GC.KeepAlive into finally for slider listener marshalling Wrap the JNI invoke in try/finally so GC.KeepAlive runs even when the call throws, preventing premature collection of the listener handle. Addresses PR review feedback.
1 parent 8be59c8 commit 47ce547

4 files changed

Lines changed: 211 additions & 49 deletions

File tree

config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3518,7 +3518,7 @@
35183518
"groupId": "com.google.android.material",
35193519
"artifactId": "material",
35203520
"version": "1.14.0",
3521-
"nugetVersion": "1.14.0.3",
3521+
"nugetVersion": "1.14.0.4",
35223522
"nugetId": "Xamarin.Google.Android.Material",
35233523
"comments": "Requires API-34"
35243524
},
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using System;
2+
using Android.Runtime;
3+
4+
namespace Google.Android.Material.Slider;
5+
6+
// Hand-written add/remove listener methods for Slider and RangeSlider.
7+
// The auto-generated versions are removed from Metadata.xml because the base interfaces
8+
// (BaseOnChangeListener, BaseOnSliderTouchListener) use erased generics that cause
9+
// ACW type erasure clashes and implementor failures. These manual implementations use
10+
// the correct JNI signature while accepting the typed sub-interfaces directly.
11+
// This pattern (remove in metadata + re-add in Additions) is standard in .NET Android bindings.
12+
13+
public partial class Slider
14+
{
15+
const string _addOnChangeListenerJni = "(Lcom/google/android/material/slider/BaseOnChangeListener;)V";
16+
const string _removeOnChangeListenerJni = "(Lcom/google/android/material/slider/BaseOnChangeListener;)V";
17+
const string _addOnSliderTouchListenerJni = "(Lcom/google/android/material/slider/BaseOnSliderTouchListener;)V";
18+
const string _removeOnSliderTouchListenerJni = "(Lcom/google/android/material/slider/BaseOnSliderTouchListener;)V";
19+
20+
public unsafe void AddOnChangeListener(Slider.IOnChangeListener listener)
21+
{
22+
const string __id = "addOnChangeListener." + _addOnChangeListenerJni;
23+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
24+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
25+
try
26+
{
27+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
28+
}
29+
finally
30+
{
31+
GC.KeepAlive(listener);
32+
}
33+
}
34+
35+
public unsafe void RemoveOnChangeListener(Slider.IOnChangeListener listener)
36+
{
37+
const string __id = "removeOnChangeListener." + _removeOnChangeListenerJni;
38+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
39+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
40+
try
41+
{
42+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
43+
}
44+
finally
45+
{
46+
GC.KeepAlive(listener);
47+
}
48+
}
49+
50+
public unsafe void AddOnSliderTouchListener(Slider.IOnSliderTouchListener listener)
51+
{
52+
const string __id = "addOnSliderTouchListener." + _addOnSliderTouchListenerJni;
53+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
54+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
55+
try
56+
{
57+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
58+
}
59+
finally
60+
{
61+
GC.KeepAlive(listener);
62+
}
63+
}
64+
65+
public unsafe void RemoveOnSliderTouchListener(Slider.IOnSliderTouchListener listener)
66+
{
67+
const string __id = "removeOnSliderTouchListener." + _removeOnSliderTouchListenerJni;
68+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
69+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
70+
try
71+
{
72+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
73+
}
74+
finally
75+
{
76+
GC.KeepAlive(listener);
77+
}
78+
}
79+
}
80+
81+
public partial class RangeSlider
82+
{
83+
const string _addOnChangeListenerJni = "(Lcom/google/android/material/slider/BaseOnChangeListener;)V";
84+
const string _removeOnChangeListenerJni = "(Lcom/google/android/material/slider/BaseOnChangeListener;)V";
85+
const string _addOnSliderTouchListenerJni = "(Lcom/google/android/material/slider/BaseOnSliderTouchListener;)V";
86+
const string _removeOnSliderTouchListenerJni = "(Lcom/google/android/material/slider/BaseOnSliderTouchListener;)V";
87+
88+
public unsafe void AddOnChangeListener(RangeSlider.IOnChangeListener listener)
89+
{
90+
const string __id = "addOnChangeListener." + _addOnChangeListenerJni;
91+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
92+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
93+
try
94+
{
95+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
96+
}
97+
finally
98+
{
99+
GC.KeepAlive(listener);
100+
}
101+
}
102+
103+
public unsafe void RemoveOnChangeListener(RangeSlider.IOnChangeListener listener)
104+
{
105+
const string __id = "removeOnChangeListener." + _removeOnChangeListenerJni;
106+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
107+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
108+
try
109+
{
110+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
111+
}
112+
finally
113+
{
114+
GC.KeepAlive(listener);
115+
}
116+
}
117+
118+
public unsafe void AddOnSliderTouchListener(RangeSlider.IOnSliderTouchListener listener)
119+
{
120+
const string __id = "addOnSliderTouchListener." + _addOnSliderTouchListenerJni;
121+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
122+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
123+
try
124+
{
125+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
126+
}
127+
finally
128+
{
129+
GC.KeepAlive(listener);
130+
}
131+
}
132+
133+
public unsafe void RemoveOnSliderTouchListener(RangeSlider.IOnSliderTouchListener listener)
134+
{
135+
const string __id = "removeOnSliderTouchListener." + _removeOnSliderTouchListenerJni;
136+
Java.Interop.JniArgumentValue* __args = stackalloc Java.Interop.JniArgumentValue[1];
137+
__args[0] = new Java.Interop.JniArgumentValue(listener == null ? IntPtr.Zero : ((Java.Lang.Object)listener).Handle);
138+
try
139+
{
140+
_members.InstanceMethods.InvokeVirtualVoidMethod(__id, this, __args);
141+
}
142+
finally
143+
{
144+
GC.KeepAlive(listener);
145+
}
146+
}
147+
}
148+

source/com.google.android.material/material/PublicAPI/PublicAPI.Unshipped.txt

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,15 +1982,20 @@ Google.Android.Material.Slider.BasicLabelFormatter
19821982
Google.Android.Material.Slider.BasicLabelFormatter.BasicLabelFormatter() -> void
19831983
Google.Android.Material.Slider.BasicLabelFormatter.GetFormattedValue(float value) -> string!
19841984
Google.Android.Material.Slider.BasicLabelFormatter.InterfaceConsts
1985-
Google.Android.Material.Slider.IBaseOnChangeListener
1986-
Google.Android.Material.Slider.IBaseOnSliderTouchListener
19871985
Google.Android.Material.Slider.ILabelFormatter
19881986
Google.Android.Material.Slider.ILabelFormatter.GetFormattedValue(float p0) -> string!
19891987
Google.Android.Material.Slider.ISliderOrientation
19901988
Google.Android.Material.Slider.ITickVisibilityMode
19911989
Google.Android.Material.Slider.LabelFormatter
19921990
Google.Android.Material.Slider.LabelFormatterConsts
19931991
Google.Android.Material.Slider.RangeSlider
1992+
Google.Android.Material.Slider.RangeSlider.AddOnChangeListener(Google.Android.Material.Slider.RangeSlider.IOnChangeListener! listener) -> void
1993+
Google.Android.Material.Slider.RangeSlider.AddOnSliderTouchListener(Google.Android.Material.Slider.RangeSlider.IOnSliderTouchListener! listener) -> void
1994+
Google.Android.Material.Slider.RangeSlider.ChangeEventArgs
1995+
Google.Android.Material.Slider.RangeSlider.ChangeEventArgs.ChangeEventArgs(Google.Android.Material.Slider.RangeSlider! p0, float p1, bool p2) -> void
1996+
Google.Android.Material.Slider.RangeSlider.ChangeEventArgs.P0.get -> Google.Android.Material.Slider.RangeSlider!
1997+
Google.Android.Material.Slider.RangeSlider.ChangeEventArgs.P1.get -> float
1998+
Google.Android.Material.Slider.RangeSlider.ChangeEventArgs.P2.get -> bool
19941999
Google.Android.Material.Slider.RangeSlider.IOnChangeListener
19952000
Google.Android.Material.Slider.RangeSlider.IOnChangeListener.OnValueChange(Google.Android.Material.Slider.RangeSlider! p0, float p1, bool p2) -> void
19962001
Google.Android.Material.Slider.RangeSlider.IOnSliderTouchListener
@@ -2000,17 +2005,40 @@ Google.Android.Material.Slider.RangeSlider.RangeSlider(Android.Content.Context!
20002005
Google.Android.Material.Slider.RangeSlider.RangeSlider(Android.Content.Context! context, Android.Util.IAttributeSet? attrs) -> void
20012006
Google.Android.Material.Slider.RangeSlider.RangeSlider(Android.Content.Context! context, Android.Util.IAttributeSet? attrs, int defStyleAttr) -> void
20022007
Google.Android.Material.Slider.RangeSlider.RangeSlider(nint javaReference, Android.Runtime.JniHandleOwnership transfer) -> void
2008+
Google.Android.Material.Slider.RangeSlider.RemoveOnChangeListener(Google.Android.Material.Slider.RangeSlider.IOnChangeListener! listener) -> void
2009+
Google.Android.Material.Slider.RangeSlider.RemoveOnSliderTouchListener(Google.Android.Material.Slider.RangeSlider.IOnSliderTouchListener! listener) -> void
2010+
Google.Android.Material.Slider.RangeSlider.StartTrackingTouchEventArgs
2011+
Google.Android.Material.Slider.RangeSlider.StartTrackingTouchEventArgs.P0.get -> Google.Android.Material.Slider.RangeSlider!
2012+
Google.Android.Material.Slider.RangeSlider.StartTrackingTouchEventArgs.StartTrackingTouchEventArgs(Google.Android.Material.Slider.RangeSlider! p0) -> void
2013+
Google.Android.Material.Slider.RangeSlider.StopTrackingTouchEventArgs
2014+
Google.Android.Material.Slider.RangeSlider.StopTrackingTouchEventArgs.P0.get -> Google.Android.Material.Slider.RangeSlider!
2015+
Google.Android.Material.Slider.RangeSlider.StopTrackingTouchEventArgs.StopTrackingTouchEventArgs(Google.Android.Material.Slider.RangeSlider! p0) -> void
20032016
Google.Android.Material.Slider.Slider
2017+
Google.Android.Material.Slider.Slider.AddOnChangeListener(Google.Android.Material.Slider.Slider.IOnChangeListener! listener) -> void
2018+
Google.Android.Material.Slider.Slider.AddOnSliderTouchListener(Google.Android.Material.Slider.Slider.IOnSliderTouchListener! listener) -> void
2019+
Google.Android.Material.Slider.Slider.ChangeEventArgs
2020+
Google.Android.Material.Slider.Slider.ChangeEventArgs.ChangeEventArgs(Google.Android.Material.Slider.Slider! p0, float p1, bool p2) -> void
2021+
Google.Android.Material.Slider.Slider.ChangeEventArgs.P0.get -> Google.Android.Material.Slider.Slider!
2022+
Google.Android.Material.Slider.Slider.ChangeEventArgs.P1.get -> float
2023+
Google.Android.Material.Slider.Slider.ChangeEventArgs.P2.get -> bool
20042024
Google.Android.Material.Slider.Slider.IOnChangeListener
20052025
Google.Android.Material.Slider.Slider.IOnChangeListener.OnValueChange(Google.Android.Material.Slider.Slider! p0, float p1, bool p2) -> void
20062026
Google.Android.Material.Slider.Slider.IOnSliderTouchListener
20072027
Google.Android.Material.Slider.Slider.IOnSliderTouchListener.OnStartTrackingTouch(Google.Android.Material.Slider.Slider! p0) -> void
20082028
Google.Android.Material.Slider.Slider.IOnSliderTouchListener.OnStopTrackingTouch(Google.Android.Material.Slider.Slider! p0) -> void
2029+
Google.Android.Material.Slider.Slider.RemoveOnChangeListener(Google.Android.Material.Slider.Slider.IOnChangeListener! listener) -> void
2030+
Google.Android.Material.Slider.Slider.RemoveOnSliderTouchListener(Google.Android.Material.Slider.Slider.IOnSliderTouchListener! listener) -> void
20092031
Google.Android.Material.Slider.Slider.SetEnabled(bool p0) -> void
20102032
Google.Android.Material.Slider.Slider.Slider(Android.Content.Context! context) -> void
20112033
Google.Android.Material.Slider.Slider.Slider(Android.Content.Context! context, Android.Util.IAttributeSet? attrs) -> void
20122034
Google.Android.Material.Slider.Slider.Slider(Android.Content.Context! context, Android.Util.IAttributeSet? attrs, int defStyleAttr) -> void
20132035
Google.Android.Material.Slider.Slider.Slider(nint javaReference, Android.Runtime.JniHandleOwnership transfer) -> void
2036+
Google.Android.Material.Slider.Slider.StartTrackingTouchEventArgs
2037+
Google.Android.Material.Slider.Slider.StartTrackingTouchEventArgs.P0.get -> Google.Android.Material.Slider.Slider!
2038+
Google.Android.Material.Slider.Slider.StartTrackingTouchEventArgs.StartTrackingTouchEventArgs(Google.Android.Material.Slider.Slider! p0) -> void
2039+
Google.Android.Material.Slider.Slider.StopTrackingTouchEventArgs
2040+
Google.Android.Material.Slider.Slider.StopTrackingTouchEventArgs.P0.get -> Google.Android.Material.Slider.Slider!
2041+
Google.Android.Material.Slider.Slider.StopTrackingTouchEventArgs.StopTrackingTouchEventArgs(Google.Android.Material.Slider.Slider! p0) -> void
20142042
Google.Android.Material.Slider.SliderOrientation
20152043
Google.Android.Material.Slider.SliderOrientationConsts
20162044
Google.Android.Material.Slider.TickVisibilityMode
@@ -6721,8 +6749,6 @@ virtual Google.Android.Material.SideSheet.SideSheetDialog.DismissWithSheetAnimat
67216749
virtual Google.Android.Material.SideSheet.SideSheetDialog.SetFitsSystemWindows(bool p0) -> void
67226750
virtual Google.Android.Material.SideSheet.SideSheetDialog.SetSheetEdge(int p0) -> void
67236751
virtual Google.Android.Material.Slider.RangeSlider.ActiveThumbIndex.get -> int
6724-
virtual Google.Android.Material.Slider.RangeSlider.AddOnChangeListener(Google.Android.Material.Slider.IBaseOnChangeListener! listener) -> void
6725-
virtual Google.Android.Material.Slider.RangeSlider.AddOnSliderTouchListener(Google.Android.Material.Slider.IBaseOnSliderTouchListener! listener) -> void
67266752
virtual Google.Android.Material.Slider.RangeSlider.Centered.get -> bool
67276753
virtual Google.Android.Material.Slider.RangeSlider.Centered.set -> void
67286754
virtual Google.Android.Material.Slider.RangeSlider.ClearOnChangeListeners() -> void
@@ -6744,8 +6770,6 @@ virtual Google.Android.Material.Slider.RangeSlider.MinSeparation.get -> float
67446770
virtual Google.Android.Material.Slider.RangeSlider.MinSeparation.set -> void
67456771
virtual Google.Android.Material.Slider.RangeSlider.OnSaveInstanceState() -> Android.OS.IParcelable!
67466772
virtual Google.Android.Material.Slider.RangeSlider.PickActiveThumb() -> bool
6747-
virtual Google.Android.Material.Slider.RangeSlider.RemoveOnChangeListener(Google.Android.Material.Slider.IBaseOnChangeListener! listener) -> void
6748-
virtual Google.Android.Material.Slider.RangeSlider.RemoveOnSliderTouchListener(Google.Android.Material.Slider.IBaseOnSliderTouchListener! listener) -> void
67496773
virtual Google.Android.Material.Slider.RangeSlider.ScheduleTooltipTimeout() -> void
67506774
virtual Google.Android.Material.Slider.RangeSlider.SetActiveThumbIndex(int index) -> void
67516775
virtual Google.Android.Material.Slider.RangeSlider.SetCustomThumbDrawable(Android.Graphics.Drawables.Drawable! drawable) -> void
@@ -6838,8 +6862,6 @@ virtual Google.Android.Material.Slider.RangeSlider.ValueTo.set -> void
68386862
virtual Google.Android.Material.Slider.RangeSlider.Values.get -> System.Collections.Generic.IList<Java.Lang.Float!>!
68396863
virtual Google.Android.Material.Slider.RangeSlider.Values.set -> void
68406864
virtual Google.Android.Material.Slider.Slider.ActiveThumbIndex.get -> int
6841-
virtual Google.Android.Material.Slider.Slider.AddOnChangeListener(Google.Android.Material.Slider.IBaseOnChangeListener! listener) -> void
6842-
virtual Google.Android.Material.Slider.Slider.AddOnSliderTouchListener(Google.Android.Material.Slider.IBaseOnSliderTouchListener! listener) -> void
68436865
virtual Google.Android.Material.Slider.Slider.Centered.get -> bool
68446866
virtual Google.Android.Material.Slider.Slider.Centered.set -> void
68456867
virtual Google.Android.Material.Slider.Slider.ClearOnChangeListeners() -> void
@@ -6859,8 +6881,6 @@ virtual Google.Android.Material.Slider.Slider.LabelBehavior.get -> int
68596881
virtual Google.Android.Material.Slider.Slider.LabelBehavior.set -> void
68606882
virtual Google.Android.Material.Slider.Slider.MinSeparation.get -> float
68616883
virtual Google.Android.Material.Slider.Slider.PickActiveThumb() -> bool
6862-
virtual Google.Android.Material.Slider.Slider.RemoveOnChangeListener(Google.Android.Material.Slider.IBaseOnChangeListener! listener) -> void
6863-
virtual Google.Android.Material.Slider.Slider.RemoveOnSliderTouchListener(Google.Android.Material.Slider.IBaseOnSliderTouchListener! listener) -> void
68646884
virtual Google.Android.Material.Slider.Slider.ScheduleTooltipTimeout() -> void
68656885
virtual Google.Android.Material.Slider.Slider.SetActiveThumbIndex(int index) -> void
68666886
virtual Google.Android.Material.Slider.Slider.SetCustomThumbDrawable(Android.Graphics.Drawables.Drawable! drawable) -> void

0 commit comments

Comments
 (0)