Create and update slim/native platform interop bindings for Android in .NET MAUI and .NET for Android projects. Guides through creating Java/Kotlin wrappers, configuring Gradle projects, resolving Maven dependencies, generating C# bindings, and integrating native Android libraries using the Native Library Interop (NLI) approach. Use when asked about Android bindings, AAR/JAR integration, Kotlin interop, Maven dependencies, or bridging native Android SDKs to .NET.
Activate this skill when the user asks:
This skill guides the creation of Native Library Interop (Slim Bindings) for Android. This modern approach creates a thin native Java/Kotlin wrapper exposing only the APIs you need from a native Android library, making bindings easier to create and maintain.
| Scenario | Recommended Approach | |----------|---------------------| | Need only a subset of library functionality | Slim Bindings | | Easier maintenance when SDK updates | Slim Bindings | | Prefer working in Java/Kotlin for wrapper | Slim Bindings | | Better isolation from breaking changes | Slim Bindings | | Complex libraries with many dependencies | Slim Bindings | | Need entire library API surface | Traditional Bindings | | Creating bindings for third-party developers | Traditional Bindings | | Already maintaining traditional bindings | Traditional Bindings |
| Parameter | Required | Example | Notes |
|-----------|----------|---------|-------|
| libraryName | yes | FirebaseMessaging, OkHttp | Name of the native Android library to bind |
| bindingProjectName | yes | MyBinding.Android | Name for the C# binding project |
| dependencySource | no | maven, aar, jar | How the native library is distributed |
| targetFrameworks | no | net9.0-android | Target frameworks (default: latest .NET Android) |
| exposedApis | no | List of specific APIs | Which native APIs to expose (helps scope the wrapper) |
| mavenCoordinates | no | com.example:library:1.0.0 | Maven coordinates if library is from Maven repository |
MyBinding/
android/
native/ # Android Studio/Gradle project
app/
src/main/
java/com/example/mybinding/
DotnetMyBinding.java # Java wrapper implementation
kotlin/com/example/mybinding/
DotnetMyBinding.kt # Or Kotlin wrapper
build.gradle.kts
settings.gradle.kts
build.gradle.kts
MyBinding.Android.Binding/
MyBinding.Android.Binding.csproj
Transforms/
Metadata.xml
sample/
MauiSample/ # Sample MAUI app
MauiSample.csproj
MainPage.xaml.cs
README.md
For detailed code examples and full implementation walkthroughs, see references/android-slim-bindings-implementation.md.
Before creating any bindings, analyze the complete dependency tree of your target library. This is the most critical step and where most binding projects fail.
Prerequisites: JDK 17+, Android SDK with ANDROID_HOME set, .NET SDK 9+. You don't need Gradle installed globally; the Gradle Wrapper downloads the correct version automatically.
Choose one of these approaches:
gradle init with Wrapper (recommended for CLI-based projects: scaffold with Gradle using the Wrapper, then convert to an Android library)After project creation, configure settings.gradle.kts, root build.gradle.kts, and app/build.gradle.kts with your library dependency.
./gradlew app:dependencies --configuration releaseRuntimeClasspath
resolution strategy.
Understanding the output: -> = version conflict resolution, (*) = deduplication, (c) = constraint.
Create a Java or Kotlin wrapper in app/src/main/java/ (or kotlin/) that exposes only the APIs you need. Key guidelines:
Dotnet for clarity@JvmStatic on all Kotlin methods for static access from C#object in Kotlin for singleton pattern./gradlew :app:assembleRelease
# Output: app/build/outputs/aar/app-release.aar
dotnet new androidbinding -n MyBinding.Android.Binding
Key .csproj elements:
< reference the built AARAndroidLibrary>< NuGet packages for transitive dependenciesPackageReference><AndroidMavenLibrary Bind=" Maven deps without NuGet equivalentfalse">< compile-time only dependenciesAndroidIgnoredJavaDependency>Configure Transforms/Metadata.xml for namespace renaming and parameter names.
Build and resolve XA4241/XA4242 errors using this decision tree:
For each unsatisfied dependency:
Is there a XA4242 suggestion?
Install the suggested NuGet package
Is the dependency needed from C#?
Find/create a binding NuGet or create your own binding
Use AndroidMavenLibrary with Bind="false"
Is it a compile-time only dependency (annotations, processors)?
Use AndroidIgnoredJavaDependency
Create a separate binding project or include AAR/JAR directly
| Maven Artifact | NuGet Package |
|----------------|---------------|
| androidx.annotation:annotation | Xamarin.AndroidX.Annotation |
| androidx.core:core | Xamarin.AndroidX.Core |
| androidx.core:core-ktx | Xamarin.AndroidX.Core.Core.Ktx |
| androidx.appcompat:appcompat | Xamarin.AndroidX.AppCompat |
| androidx.fragment:fragment | Xamarin.AndroidX.Fragment |
| androidx.activity:activity | Xamarin.AndroidX.Activity |
| androidx.recyclerview:recyclerview | Xamarin.AndroidX.RecyclerView |
| androidx.lifecycle:lifecycle-common | Xamarin.AndroidX.Lifecycle.Common |
| org.jetbrains.kotlin:kotlin-stdlib | Xamarin.Kotlin.StdLib |
| org.jetbrains.kotlinx:kotlinx-coroutines-core | Xamarin.KotlinX.Coroutines.Core |
| com.google.android.material:material | Xamarin.Google.Android.Material |
| com.squareup.okhttp3:okhttp | Square.OkHttp3 |
| com.google.code.gson:gson | GoogleGson |
dotnet package search "artifact=androidx.core:core" --source https://api.nuget.org/v3/index.json
Edit Transforms/Metadata.xml to rename packages, classes, parameters, and remove internal types. Examine obj/Debug/net9.0-android/api.xml after building to construct correct XPath expressions.
dotnet build -c Release
Add a conditional <ProjectReference>, initialize in MauiProgram.cs using ConfigureLifecycleEvents, and implement callback interfaces by extending Java.Lang.Object.
app/build.gradle.kts./gradlew app:dependencies./gradlew :app:assembleRelease.csprojMetadata.xml for new classes/methodsFor detailed update instructions, see references/android-slim-bindings-implementation.md.
| Error | Cause | Solution |
|-------|-------|----------|
| XA4241 / XA4242 | Missing transitive dependency | Use NuGet, AndroidMavenLibrary Bind="false", or AndroidIgnoredJavaDependency |
| "Type is defined multiple times" | Duplicate dependency | Check NuGet/AAR overlap, use Bind="false" |
| "Class does not implement interface member" | Covariant return types | Add custom implementation in Additions/ folder |
| "Cannot find symbol" | Missing Gradle dependency | Verify build.gradle.kts dependencies, rebuild AAR |
| NoClassDefFoundError (runtime) | Dependency ignored incorrectly | Remove from AndroidIgnoredJavaDependency, satisfy properly |
| UnsatisfiedLinkError (runtime) | Missing .so native library | Include via <AndroidNativeLibrary>, check ABI compatibility |
| Callback not invoked | Wrong thread / GC'd reference | Use MainThread.BeginInvokeOnMainThread(), hold strong reference |
For detailed troubleshooting with code examples, see references/android-slim-bindings-implementation.md.
| Java/Kotlin Type | C# Type | Notes |
|------------------|---------|-------|
| String | string | Direct mapping |
| boolean / Boolean | bool | Direct mapping |
| int / Integer | int | Direct mapping |
| long / Long | long | Direct mapping |
| double / Double | double | Direct mapping |
| float / Float | float | Direct mapping |
| byte[] | byte[] | Direct mapping |
| Context | Android.Content.Context | Pass from platform |
| View | Android.Views.View | For view creation |
| JSONObject | Org.Json.JSONObject | For complex data |
| Callback interface | IJavaObject implementation | See callback pattern |
| Avoid | Use Instead | |-------|-------------| | Kotlin coroutines | Callback interfaces | | Kotlin lambdas | Java-style interfaces | | Kotlin data classes | Simple classes with getters | | Kotlin sealed classes | Enums or class hierarchy | | Generics (complex) | Specific types or Object | | Rx/Flow observables | Callback interfaces |
| Item | Purpose |
|------|---------|
| <AndroidLibrary> | Include AAR/JAR in binding |
| <AndroidMavenLibrary> | Download and include from Maven |
| <AndroidIgnoredJavaDependency> | Ignore a dependency (compile-time only) |
| <AndroidNativeLibrary> | Include .so files |
| <TransformFile> | Metadata transform files |
| <PackageReference> | NuGet package reference |
| Attribute | Values | Purpose |
|-----------|--------|---------|
| Bind | true/false | Whether to generate C# bindings |
| Pack | true/false | Whether to include in NuGet package |
| JavaArtifact | groupId:artifactId | Declare what Maven artifact this satisfies |
| JavaVersion | version | Version of the Maven artifact |
| Repository | Central/Google/URL | Maven repository to download from |
When assisting with Android slim bindings, provide:
.csproj with proper dependency referencesAlways verify:
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer