diff --git a/Documentation/guides/BuildProcess.md b/Documentation/guides/BuildProcess.md
index 85d0e3ed505..9e3608c77ff 100644
--- a/Documentation/guides/BuildProcess.md
+++ b/Documentation/guides/BuildProcess.md
@@ -663,6 +663,24 @@ when packaing Release applications.
See [Lint Help](http://www.androiddocs.com/tools/help/lint.html) for more details on
the android `lint` tooling.
+- **AndroidGenerateJniMarshalMethods** – A bool property which
+ enables generating of JNI marshal methods as part of the build
+ process. This greatly reduces the System.Reflection usage in the
+ binding helper code.
+
+ By default this will be set to False. If the developers wish to use
+ the new JNI marshal methods feature, they can set
+
+ True
+
+ in their csproj. Alternatively provide the property on the command
+ line via
+
+ /p:AndroidGenerateJniMarshalMethods=True
+
+ **Experimental**. Added in Xamarin.Android 8.4.
+ The default value is False.
+
### Binding Project Build Properties
The following MSBuild properties are used with
@@ -761,7 +779,7 @@ resources.
- **AndroidUseAapt2** – A bool property which allows the developer to
control the use of the `aapt2` tool for packaging.
By default this will be set to false and we will use `aapt`.
- If the developer wishes too use the new `aapt2` functionality
+ If the developer wishes to use the new `aapt2` functionality
they can set
True
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AndroidLinkContext.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AndroidLinkContext.cs
new file mode 100644
index 00000000000..47503b2965f
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AndroidLinkContext.cs
@@ -0,0 +1,16 @@
+using Mono.Linker;
+using Mono.Cecil;
+
+namespace MonoDroid.Tuner
+{
+ public class AndroidLinkContext : LinkContext
+ {
+ public AndroidLinkContext (Pipeline pipeline, AssemblyResolver resolver)
+ : base (pipeline, resolver) {}
+
+ public AndroidLinkContext (Pipeline pipeline, AssemblyResolver resolver, ReaderParameters readerParameters, UnintializedContextFactory factory)
+ : base (pipeline, resolver, readerParameters, factory) {}
+
+ public bool PreserveJniMarshalMethods { get; set; }
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs
index 89b7b408171..8bef4f076a7 100644
--- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs
@@ -37,7 +37,7 @@ static void Run (Pipeline pipeline, LinkContext context)
static LinkContext CreateLinkContext (LinkerOptions options, Pipeline pipeline, ILogger logger)
{
- var context = new LinkContext (pipeline, options.Resolver);
+ var context = new AndroidLinkContext (pipeline, options.Resolver);
if (options.DumpDependencies) {
var prepareDependenciesDump = context.Annotations.GetType ().GetMethod ("PrepareDependenciesDump", new Type[] {});
if (prepareDependenciesDump != null)
@@ -51,6 +51,7 @@ static LinkContext CreateLinkContext (LinkerOptions options, Pipeline pipeline,
context.SymbolReaderProvider = new DefaultSymbolReaderProvider (true);
context.SymbolWriterProvider = new DefaultSymbolWriterProvider ();
context.OutputDirectory = options.OutputDirectory;
+ context.PreserveJniMarshalMethods = options.PreserveJniMarshalMethods;
return context;
}
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs
index d8a6af1ff74..8bd0992ef02 100644
--- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs
@@ -22,5 +22,6 @@ class LinkerOptions
public bool DumpDependencies { get; set; }
public string HttpClientHandlerType { get; set; }
public string TlsProvider { get; set; }
+ public bool PreserveJniMarshalMethods { get; set; }
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs
index 6ef16b20026..3b0de21ad5e 100644
--- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs
@@ -22,7 +22,7 @@ public override void Process (LinkContext context)
marshalTypes.Clear ();
base.Process (context);
- if (UpdateMarshalTypes ())
+ if (PreserveJniMarshalMethods () && UpdateMarshalTypes ())
base.Process (context);
}
@@ -196,6 +196,14 @@ bool UpdateMarshalRegisterMethod (MethodDefinition method, HashSet marke
return true;
}
+ bool PreserveJniMarshalMethods ()
+ {
+ if (_context is AndroidLinkContext ac)
+ return ac.PreserveJniMarshalMethods;
+
+ return false;
+ }
+
// If this is one of our infrastructure methods that has [Register], like:
// [Register ("hasWindowFocus", "()Z", "GetHasWindowFocusHandler")],
// we need to preserve the "GetHasWindowFocusHandler" method as well.
@@ -207,7 +215,7 @@ protected override void DoAdditionalMethodProcessing (MethodDefinition method)
return;
MethodDefinition marshalMethod;
- if (method.TryGetMarshalMethod (nativeMethod, signature, out marshalMethod)) {
+ if (PreserveJniMarshalMethods () && method.TryGetMarshalMethod (nativeMethod, signature, out marshalMethod)) {
MarkMethod (marshalMethod);
marshalTypes.Add (marshalMethod.DeclaringType);
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs
index 86d9015e703..954d17eaa58 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs
@@ -51,6 +51,8 @@ public class LinkAssemblies : Task, ML.ILogger
public string TlsProvider { get; set; }
+ public bool PreserveJniMarshalMethods { get; set; }
+
IEnumerable GetRetainAssemblies (DirectoryAssemblyResolver res)
{
List retainList = null;
@@ -83,6 +85,7 @@ public override bool Execute ()
Log.LogDebugMessage (" LinkOnlyNewerThan: {0}", LinkOnlyNewerThan);
Log.LogDebugMessage (" HttpClientHandlerType: {0}", HttpClientHandlerType);
Log.LogDebugMessage (" TlsProvider: {0}", TlsProvider);
+ Log.LogDebugMessage (" PreserveJniMarshalMethods: {0}", PreserveJniMarshalMethods);
var rp = new ReaderParameters {
InMemory = true,
@@ -115,6 +118,7 @@ bool Execute (DirectoryAssemblyResolver res)
options.DumpDependencies = DumpDependencies;
options.HttpClientHandlerType = HttpClientHandlerType;
options.TlsProvider = TlsProvider;
+ options.PreserveJniMarshalMethods = PreserveJniMarshalMethods;
var skiplist = new List ();
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
index 0c0ef54ffb3..89133632461 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
@@ -575,6 +575,7 @@
PreserveNewest
+
<_MonoAndroidEnum Include="$(AndroidGeneratedClassDirectory)\Android.Content.PM.LaunchMode.cs" />
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index 19fdd25d1ac..640a4043581 100755
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -303,6 +303,8 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
<_InstantRunEnabled Condition=" '$(_InstantRunEnabled)' == '' ">False
<_AndroidBuildPropertiesCache>$(IntermediateOutputPath)build.props
+ False
+
@@ -2057,6 +2059,7 @@ because xbuild doesn't support framework reference assemblies.
LinkSkip="$(AndroidLinkSkip)"
LinkDescriptions="@(LinkDescription)"
ProguardConfiguration="$(_ProguardProjectConfiguration)"
+ PreserveJniMarshalMethods="$(AndroidGenerateJniMarshalMethods)"
EnableProguard="$(AndroidEnableProguard)"
DumpDependencies="$(LinkerDumpDependencies)"
ResolvedAssemblies="@(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')"