Skip to content

Compose: navigation-compose @Composable surface (NavHost, composable, rememberNavController, DialogHost) not bound — every Kt wrapper is empty #1444

Description

@jonathanpeppers

Summary

Xamarin.AndroidX.Navigation.Compose ships with the navigator classes bound (ComposeNavigator, DialogNavigator, their Destination types and *DestinationBuilder types) but none of the user-facing @Composable entry points are reachable from C#.

Specifically, the following *Kt wrapper classes are bound as empty containers — class declarations exist but they have zero static methods:

  • AndroidX.Navigation.Compose.NavHostKt — should expose NavHost(navController, startDestination, modifier, ...) { … }
  • AndroidX.Navigation.Compose.NavHostControllerKt — should expose rememberNavController(vararg navigators: Navigator<…>): NavHostController
  • AndroidX.Navigation.Compose.NavGraphBuilderKt — should expose NavGraphBuilder.composable(route, arguments, deepLinks, content) and NavGraphBuilder.dialog(…)
  • AndroidX.Navigation.Compose.DialogHostKt — should expose DialogHost(dialogNavigator)
  • AndroidX.Navigation.Compose.NavBackStackEntryProviderKt — should expose NavBackStackEntry.LocalOwnersProvider(saveableStateHolder, content)

This makes the entire navigation surface unusable without raw JNI: there is no way to build a nav graph, render a NavHost, or call composable("route") from bound API alone.

Library / NuGet

Verified state today (commit eb2f50b)

The PublicAPI.Unshipped.txt is 3,479 bytes total. Every Kt class binds as just:

AndroidX.Navigation.Compose.NavHostKt
override AndroidX.Navigation.Compose.NavHostKt.JniPeerMembers.get -> Java.Interop.JniPeerMembers!

Compare to what the Kotlin source actually exposes (e.g. https://developer.android.com/reference/kotlin/androidx/navigation/compose/package-summary):

Method Class Status
NavHost(NavHostController, String, …) { … } NavHostKt missing
NavHost(NavHostController, NavGraph, …) NavHostKt missing
rememberNavController(vararg Navigator<…>) NavHostControllerKt missing
NavGraphBuilder.composable(String, …) NavGraphBuilderKt missing
NavGraphBuilder.dialog(String, …) NavGraphBuilderKt missing
NavGraphBuilder.navigation(String, String, …) NavGraphBuilderKt missing
NavBackStackEntry.LocalOwnersProvider(…) NavBackStackEntryProviderKt missing
DialogHost(DialogNavigator) DialogHostKt missing

All of these have @Composable annotations. The empty-*Kt-wrapper pattern affects them even though they are not all hash-mangled — for example, androidx.compose.ui.res.PainterResources_androidKt.painterResource(Int, Composer, Int): Painter has no @JvmInline value class parameters yet is also dropped from its wrapper (see the companion Painter issue). The root cause is therefore unlikely to be only dotnet/java-interop#1440; there appears to be a separate binder rule dropping @Composable statics from *Kt wrappers in this Compose surface area.

Metadata.xml today

source/androidx.navigation/navigation-compose-android/Transforms/Metadata.xml contains only two managedReturn adjustments for createDestination. There are no <remove-node> entries that would explain why all the @Composable statics are dropped.

Reproduction / evidence

compose-net could not bind navigation at all via the binding. The compose-net tracking issue jonathanpeppers/compose-net#60 confirms this gap end-to-end. (No hand-written JNI bridge has been attempted in compose-net yet — the binding shape was inspected and found empty.)

Suggested fix

Investigate why the @Composable statics on NavHostKt, NavHostControllerKt, NavGraphBuilderKt, NavBackStackEntryProviderKt, and DialogHostKt are dropped — there is no Metadata.xml customization removing them, so the binder pipeline itself is filtering them out. Likely related to the @Composable annotation plus return type / receiver type metadata; possibly the same root cause as the painterResource drop (see the companion Painter issue).

If specific overloads must be reintroduced via add-node, that is acceptable as a tactical fix, but the underlying binder behaviour should be investigated since this also affects a large surface in material3 and the other Compose libraries.

Cross-references

  • compose-net tracking: jonathanpeppers/compose-net#60
  • Master inline-class blocker: dotnet/java-interop#1440 — relevant to some overloads with inline-class parameters (e.g. Modifier, Dp) but the consistently empty *Kt wrappers across this binding suggest the root cause is a separate filter dropping @Composable statics independently of name mangling.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions