You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
jpobst opened this issue
Jan 31, 2025
· 2 comments
Labels
generatorIssues binding a Java library (generator, class-parse, etc.)proposalIssue raised for discussion, we do not even know if the change would be desirable yet
The MAUI Community Toolkit provides guidance on creating "slim bindings" called "Native Method Interop". There are a few downsides to this approach:
It requires non-trivial Java knowledge to set up Android Studio, a Java Binding project, and write a Java wrapper API.
Integrating the wrapped .jar and potentially its dependencies into the managed app can be tricky, getting its versions to align with .jar files pulled in through NuGet packages.
Once we're already down the path of asking users to write the APIs by hand, could we use Roslyn source generators to allow them to do the same in C#?
Example
Using the example from MAUI Community Toolkit, we could allow the user to write the C# API that matches the Java API to bind:
// Java API to bindpackagecom.facebook;
publicclassFacebookSdk {
publicfinalvoidsetIsDebugEnabled (Booleanvalue) { ... }
}
// C# user writes[AndroidBindingType("com.facebook.FacebookSdk")]publicpartialclassFacebookSdk:Java.Lang.Object{[AndroidBindingMethod("setIsDebugEnabled")]publicpartialvoidSetIsDebugEnabled(boolvalue);}
We could then use a Roslyn source generator to fill in the plumbing in a generated partial class:
// Additional C# that gets generated[global::Android.Runtime.Register("com/facebook/FacebookSdk",DoNotGenerateAcw=true)]publicpartialclassFacebookSdk{[Register("setIsDebugEnabled","(Z)V","")]publicpartialunsafevoidSetIsDebugEnabled(boolvalue){conststring__id="setIsDebugEnabled.(Z)V";try{JniArgumentValue*__args=stackallocJniArgumentValue[1];__args[0]=newJniArgumentValue(nonRoot);_members.InstanceMethods.InvokeVirtualVoidMethod(__id,this,__args);}finally{}}}
Vague Typing
This proposal could also incorporate the principles of Vaguely Typed Slim Bindings, allowing the user to bind as much or as little as they want.
These bindings should compose well with existing bound libraries. Imagine a MapActivity that subclasses androidx.activity.Activity. Adding the Xamarin.AndroidX.Activity NuGet package would allow your bound type to easily subclass the "real" class:
The largest downside is likely the lack of compile-time checking. If a user misspells a Java type or method name, we won't have tooling that can verify it, so they will receive a runtime error. Same if the user provides incorrect parameter or return types, or provides the wrong number of parameters.
The text was updated successfully, but these errors were encountered:
jpobst
added
generator
Issues binding a Java library (generator, class-parse, etc.)
proposal
Issue raised for discussion, we do not even know if the change would be desirable yet
labels
Jan 31, 2025
All the data is there to provide build time checking. We know the type they want and the methods they want so generating a .java source file and compiling that using the .jar files being referenced would produce an error. It can just be a check, it doesn't need to end up in the final app.
I mean it would be tricky, but doable. It would be an extra build step when using this feature.
generatorIssues binding a Java library (generator, class-parse, etc.)proposalIssue raised for discussion, we do not even know if the change would be desirable yet
Background
The MAUI Community Toolkit provides guidance on creating "slim bindings" called "Native Method Interop". There are a few downsides to this approach:
.jar
and potentially its dependencies into the managed app can be tricky, getting its versions to align with.jar
files pulled in through NuGet packages.Once we're already down the path of asking users to write the APIs by hand, could we use Roslyn source generators to allow them to do the same in C#?
Example
Using the example from MAUI Community Toolkit, we could allow the user to write the C# API that matches the Java API to bind:
We could then use a Roslyn source generator to fill in the plumbing in a generated partial class:
Vague Typing
This proposal could also incorporate the principles of Vaguely Typed Slim Bindings, allowing the user to bind as much or as little as they want.
Imagine the Java API:
If the user just wants to add the map pin and isn't interested in using the return value, they can bind it as
Java.Lang.Object
:If they want to interact with the
MapPin
type, they can provide as much of it as they want:Interaction with Existing Bindings
These bindings should compose well with existing bound libraries. Imagine a
MapActivity
that subclassesandroidx.activity.Activity
. Adding theXamarin.AndroidX.Activity
NuGet package would allow your bound type to easily subclass the "real" class:Downsides
The largest downside is likely the lack of compile-time checking. If a user misspells a Java type or method name, we won't have tooling that can verify it, so they will receive a runtime error. Same if the user provides incorrect parameter or return types, or provides the wrong number of parameters.
The text was updated successfully, but these errors were encountered: