Skip to content

Android

The Android host is a library module (:bare-host) published as a self-contained AAR (io.github.anderscan.ekrooh:bare-host on Maven Central, with GitHub Packages as a fallback): the Bare Kit runtime jar ships in the AAR’s libs/ and its native libs in jni/, so consumers need no separate prebuilds download.

The version tracks the framework version (single version across the npm package and the AAR, released together on the same tag — see RELEASING.md). Pin it to the framework version you depend on.

  • BareProtocol — Kotlin mirror of the binary wire protocol.
  • HostIpcCoordinator — frames in/out of the worklet’s IPC, written through one serialized writer.
  • HostPluginRegistry — maps host plugin IDs to handlers.
  • BareHandoff — parses handoff.json and deletes it as it reads it.
  • BareWebViewClient — WebView wiring: logs resource errors and confines the main frame to allowedOrigin. A link the user taps to another http(s) site opens in the system browser; a navigation without a gesture (a meta refresh, a script redirect) is only cancelled; a POST navigation is answered with an empty 403.
  • BareHostAbi — requireSupportedAbi() throws on a 32-bit-only device or in a 32-bit process (see ADR 0002).

The public API is dumped to android/api/bare-host.api; ./gradlew check runs apiCheck, so a changed signature fails the build until the dump is regenerated with ./gradlew :bare-host:apiDump and reviewed.

examples/android-app is the shell that embeds the backend and WebView:

  • The worklet runs in the Application (BareApplication + ReferenceHost), not per Activity, so rotation and a second launch do not restart the backend. MainActivity is the only exported component, with launchMode="singleTop", and its configChanges cover rotation, UI mode, density, font scale, locale and layout direction. Only the first WebView gets the bootstrap nonce; later ones log in with the session cookie.
  • The host starts the worklet with [webAssets, storage, cache], where durable storage is noBackupFilesDir/bare (moved once from the old cacheDir/bare), (a failed move falls back to the old directory and is retried each launch), reads handoff.json through BareHandoff.consume (a late handoff is still consumed after the error page is shown), injects window.__ekrooh = { bootstrap } (a one-time nonce, never the raw token; plus window.BareShell) with addDocumentStartJavaScript after a WebView feature check, and loads http://127.0.0.1:<port>/index.html.
  • The WebView has file and content access off; cleartext is allowed only to 127.0.0.1/localhost, and every backup domain is excluded.
  • A real native photo picker/camera feeds vendor.media.
repositories {
mavenCentral() // default in modern Gradle/Android Studio; no auth needed
}
dependencies {
implementation "io.github.anderscan.ekrooh:bare-host:<version>" // same version as @ekrooh/bare
}

Note: the groupId is your verified Maven Central namespace with the project’s sub-namespace appended (io.github.anderscan.ekrooh — parent io.github.anderscan is the reverse of the GitHub Pages URL and auto-verifiable via your GitHub account). If you were consuming from GitHub Packages before, the maven layout is identical — just drop the maven { url = "https://maven.pkg.github.com/AndersCan/ekrooh" } repository and the read:packages PAT wiring. No credential block is required for Maven Central.

Terminal window
npm run prebuilds # fetch Bare Kit prebuilds (prebuilds/)
./gradlew :examples:android-app:assembleDebug

The Gradle Exec tasks that build the JS inputs assume a flat node_modules (npm/yarn, or pnpm with nodeLinker=hoisted) and run from the repo root — see Android Host Build before copying the build.gradle pattern into a consumer repo.

Tests: JUnit in src/test/ (./gradlew :bare-host:testDebugUnitTest).