Update Android translations at runtime without publishing a new app version.
ReRune integrates with native stringResource(...), getString(...), Jetpack
Compose, Android Views, and XML string resources.
This public repository contains runnable integration examples and documentation for the ReRune Android SDK artifacts published on Maven Central.
This repository demonstrates the core OTA localization use case: an app can ship only default app strings while ReRune delivers additional dashboard languages after release.
The important ReRune OTA behavior shown here is remote-language delivery:
German is available from the dashboard payload even though the example apps do
not include app-owned values-de/strings.xml files. After the manifest and
locale payload are fetched, no new app-store build is needed just to add German.
Compose:
implementation("io.rerune:rerune-android-compose:0.14.0")Views:
implementation("io.rerune:rerune-android-views:0.14.0")Both top-layer artifacts expose io.rerune:rerune-android-core transitively.
compose-example: Jetpack Compose integration using nativestringResource(...)views-example: classic Android Views integration using native XML andgetString(...)
Both examples ship with a public demo otaPublishId that includes German
dashboard translations. The examples keep app string resources in the default
values/ directory only, so switching a device to German exercises ReRune
remote-only language delivery instead of app-bundled German strings.
Override it locally if needed:
./gradlew :compose-example:assembleDebug -PRERUNE_OTA_PUBLISH_ID=replace-me
./gradlew :views-example:assembleDebug -PRERUNE_OTA_PUBLISH_ID=replace-meor:
RERUNE_OTA_PUBLISH_ID=replace-me ./gradlew :compose-example:assembleDebugclass App : Application() {
override fun onCreate() {
super.onCreate()
ReRune.setup(
app = this,
otaPublishId = BuildConfig.RERUNE_OTA_PUBLISH_ID,
)
}
}override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(newBase.reRune())
}@Composable
fun ExampleScreen() {
reRuneObserveRevision {
Text(text = stringResource(R.string.title))
}
}class App : Application() {
override fun onCreate() {
super.onCreate()
ReRune.setup(
app = this,
otaPublishId = BuildConfig.RERUNE_OTA_PUBLISH_ID,
)
ReRuneViews.install(this)
}
}override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(newBase.reRune())
}titleText.text = getString(R.string.title)ReRune Android SDK 0.14.0 can expose and apply locales that exist in the
ReRune dashboard even when the APK does not contain compiled
values-<locale> resources.
The dashboard manifest is the runtime source of truth for ReRune locales. The SDK fetches every manifest locale it can reach, not only locales already present in app resources.
System language following works without an in-app picker:
- Install either example app.
- Pull to refresh once so the app fetches the ReRune manifest and locale XML.
- Set the Android system language to German.
- Restart the app. Text resolves from cached ReRune German payloads and falls back to bundled English/default resources for missing keys.
Apps with a language picker can list dashboard locales:
lifecycleScope.launch {
ReRune.availableLocalesFlow.collect { locales ->
// locale.localeTag: "de", "pt-BR", ...
// locale.isCached: payload is available offline right now
}
}Locale selection follows Android's system or per-app locale configuration. On Android 14 and newer, the SDK also publishes dashboard locales to Android's dynamic locale configuration after fetching the manifest.
- The SDK keeps bundled resources as the fallback safety net.
- New string resource keys still require an app release because Android
R.string.*ids are compiled into the app. - Compose redraw is opt-in through
reRuneObserveRevision { ... }. - Views redraw is app-owned;
reRuneOnStringsUpdated(...)only notifies. - OS-level language lists and app-store language metadata still come from the app/platform, not ReRune dashboard state.
- This repo is a showcase app repository.
./gradlew :compose-example:installDebug
./gradlew :views-example:installDebugMIT. See LICENSE.
