Skip to content

Commit a9312d2

Browse files
jonpryordellis1972
authored andcommitted
[Java.Interop.Tools.JavaCallableWrappers] Fix android.app.Application (#34)
android.app.Application is special: Android contructs it before the mono runtime has been initialized, requiring that the [activation constructor][0] be used for all Android.App.Application subclasses: [Application] partial class MyApp : Android.App.Application { public MyApp (IntPtr r, JniHandleOwnership transfer) : base (r, transfer) { } } As a consequence of this, the Android.App.Application..ctor() default constructor *is never used in normal use*, which means that the linker is free to remove it. This in turn means that in Release (linked) apps, *no* constructor would be present in the `MyApp` Java Callable Wrappers, because constructor generation requires that the binding assembly contain the constructor to emit. This is kinda/sorta fine, in that the Java compiler-provided default constructor would still be emitted, allowing the `MyApp` Java Callable Wrapper to be constructed, but that's only true so long as the default constructor is sufficient. Unfortunately, the default constructor isn't always sufficient: on certain Android versions (API <= 15), the Application instance isn't provided to the bootstrap `MonoRuntimeProvider.attachInfo()` method, which means that the Android.App.Application.Context property returns the wrong value. Fixing this requires updating the Java Callable Wrapper of the Application subclass to contain code to preserve the first Application instance created in the process, which in turn means the default Application constructor is no longer sufficient. Update JavaCallableWrapperGenerator so that (in Debug builds) the default Application constructor is skipped, and in *all* configurations a custom constructor is generated within the Java Callable Wrapper for android.app.Application subclasses. [0]: https://developer.xamarin.com/guides/android/under_the_hood/architecture/#Java_Activation
1 parent 73eaddc commit a9312d2

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/JavaCallableWrapperGenerator.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,8 +543,13 @@ void GenerateHeader (StreamWriter sw)
543543

544544
void GenerateBody (StreamWriter sw)
545545
{
546-
foreach (Signature ctor in ctors)
546+
foreach (Signature ctor in ctors) {
547+
if (string.IsNullOrEmpty (ctor.Params) && JniType.IsApplication (type))
548+
continue;
547549
GenerateConstructor (ctor, sw);
550+
}
551+
552+
GenerateApplicationConstructor (sw);
548553

549554
foreach (JavaFieldInfo field in exported_fields)
550555
GenerateExportedField (field, sw);
@@ -755,6 +760,19 @@ void GenerateConstructor (Signature ctor, StreamWriter sw)
755760
sw.WriteLine ("\t}");
756761
}
757762

763+
void GenerateApplicationConstructor (StreamWriter sw)
764+
{
765+
if (!JniType.IsApplication (type)) {
766+
return;
767+
}
768+
769+
sw.WriteLine ();
770+
sw.WriteLine ("\tpublic {0} ()", name);
771+
sw.WriteLine ("\t{");
772+
sw.WriteLine ("\t\tmono.MonoPackageManager.setContext (this);");
773+
sw.WriteLine ("\t}");
774+
}
775+
758776
void GenerateExportedField (JavaFieldInfo field, StreamWriter sw)
759777
{
760778
sw.WriteLine ();

0 commit comments

Comments
 (0)