Skip to content

[Xamarin.AndroidX.Compose.Runtime] Stop stripping the whole package; ship real bindings #1415

@jonathanpeppers

Description

@jonathanpeppers

The Xamarin.AndroidX.Compose.Runtime NuGet currently ships an empty managed facade. Its Transforms/Metadata.xml carries:

<remove-node path="/api/package" />

with a comment that Compose is Kotlin-only and "does not make sense for C# until parsing of kotlin and transpiling to c# is ready (if ever)".

That's too pessimistic — for the runtime types specifically, the binding generator does fine on the AAR if you add a small, bounded set of targeted <remove-node> entries. I have a proven-working rebinding of androidx.compose.runtime:runtime-android 1.9.4 in ComposeNet.Bindings.Runtime — it builds, packs, and is consumed end-to-end by a working Compose-from-C# sample app.

Requested change

  1. Delete <remove-node path="/api/package" /> from the recipe's Transforms/Metadata.xml.
  2. Port the 14 targeted <remove-node> entries from the proven-working Transforms/Metadata.xml. They cover:
    • SnapshotStateList/Map/Set + their *Kt companions (KMP collection-jvm interface erasure ⇒ Size()/Values()/EntrySet() signature mismatch with java.util.*).
    • MutableSnapshot / Snapshot.getReadObserver (Kotlin typealias (Any) -> Unit).
    • AbstractApplier<T> (abstract IApplier.insertBottomUp/TopDown(int, T) doesn't satisfy IApplier<Object> after erasure).
    • BroadcastFrameClock, PausableMonotonicFrameClock (missing CoroutineContext.Element.key override).
    • MutableIntState/LongState/FloatState/DoubleState and their non-mutable peers (primitive value accessor hides MutableState<T>.value setter).
    • MonotonicFrameClock.Key and SnapshotContextElement.Key (nested companion Key clashes with inherited CoroutineContext.Element.key).
    • ComposerKt.isAfterFirstChild (two inline-class overloads collapse to identical JVM signatures).
  3. Add <AndroidIgnoredJavaDependency Include="androidx.collection:collection-jvm:1.5.0" /> to satisfy the dependency verifier (the -android variant from Xamarin.AndroidX.Collection already satisfies it at runtime).
  4. Regenerate api/PublicApi*.txt. The reversal from "no public API" to "real bindings" adds many hundreds of public types/members; the existing baselines will fail the API compatibility check until refreshed.

Why now

Google declared Compose-first in May 2026 — android.widget.*, Fragments, RecyclerView, ViewPager are now maintenance mode. .NET for Android needs a story for hosting Compose UI from C#, and the empty-facade policy is the only thing blocking it for the runtime types. See https://github.com/jonathanpeppers/compose-net (notably NOTES.md and README.md) for the broader strategy.

Sequencing

This is the prerequisite for two companion issues (UI/Foundation/Foundation.Layout and Material3) — Runtime ships first because every other Compose recipe references real types from it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions