Skip to main content

android_app

Macro android_app 

Source
macro_rules! android_app {
    ($state_ty:ty, $build:expr $(,)?) => { ... };
    ($state_ty:ty, $state_init:expr, $build:expr $(,)?) => { ... };
}
Expand description

Bind a generated app’s State/build to the fixed Android JNI exports (a Makepad app_main! precedent).

Stamps out the twenty-two Java_dev_frust_FrustSurfaceView_native* symbols the Kotlin FrustSurfaceView declares external, each delegating to the non-generic runtime in [jni_glue]. nativeInit constructs the app’s erased view tree from a state factory and $build; the rest operate on the opaque jlong handle. The three IME exports (nativeImeApply, nativeImeState, nativeImeAction) carry the soft-keyboard state-sync contract: Kotlin pushes a whole editing state in (nativeImeApply), pulls the reconciled state back out (nativeImeState), and forwards an editor action (Enter) via nativeImeAction. nativeSetAppearance flips the app’s theme brightness from the platform’s dark-mode preference, and nativeSetReduceMotion does the same for the platform’s reduced-motion accessibility preference (a different sensor over the same transport — Settings.Global.ANIMATOR_DURATION_SCALE, not Configuration). nativeAppIsDark is the read half of the appearance seam: it returns whether the app’s currently active theme is dark, so Kotlin’s status-bar icon contrast can follow the APP’s resolved theme (which an app-forced frust::set_app_theme override may have pinned away from the platform’s own preference) instead of re-reading Configuration.uiMode directly. nativeOnDeepLink delivers a cold-start/running platform deep link into the process-wide deep-link source. nativeInitAccessibility attaches the accesskit Android adapter to the host view. Two more exports: nativeOnInsetsChanged delivers the platform window insets (SafeArea), and nativeOnBackPress routes a hardware/gesture back press through the framework (returning whether it consumed it). nativeOnSurfaceChanged also gained a trailing density argument alongside these. nativeSystemUiState returns the app-facing frust::set_system_ui_mode override slot’s packed (generation, mode) state for a per-frame Kotlin poll. Two more, additive over those seventeen: nativeSetSurfaceMode latches a translucent GPU surface pre-init (a one-way opt-in — see frust_shell_common::surface_mode’s module docs), and nativePlatformViewCommands returns the native-sibling-compositor command backlog (the differ) as JSON for Kotlin’s own per-frame poll, mirroring nativeSystemUiState’s generation-gated shape but JSON-encoded (the ViewCommand vocabulary) rather than packed into a jlong. One more: nativeSetFrameTimeline pushes the Choreographer frame timeline’s expectedPresentationTimeNanos − frameTimeNanos (API 33+, the one signal only the JVM side can read) into the scroll-sync tail — additive and optional, 0/never-called leaves the platform-view release path gate-only. nativeInit also initializes the process-wide [frust_reactive::ReactiveRuntime] (see [jni_glue::native_init]) before the state factory runs, so a State’s own construction may already create signals/controllers.

The macro is defined on every target but only expands to real code where its call site is gated, e.g. in the generated src/lib.rs:

ⓘ
#[cfg(target_os = "android")]
frust::android_app!(AppState, move |s| root.build(s));

Two forms:

  • android_app!($state_ty, $build) — $state_ty must implement Default; the state is built via <$state_ty as Default>::default.
  • android_app!($state_ty, $state_init, $build) — $state_init is a FnOnce() -> $state_ty factory (e.g. a closure or a bare function path like MyState::new), for a State that doesn’t implement Default. The 2-arg form delegates to this one.

$build is the root component’s build closure, a FnMut(&mut State) -> impl View<State> (move |s| root.build(s)).