Skip to content
The mobile SDKs are available on request. Email support@grona.ai to get access.

R8 and ProGuard

This page covers shrinking and obfuscation in release builds. The short version: your app adds no rules for Grona. The SDK’s consumer rules file is empty on purpose, and R8 keeps everything the SDK needs through your app’s own references.

grona-core ships a consumer rules file that R8 applies to your build automatically. It contains no rules, only this note:

consumer-rules.pro (bundled in grona-core)
# Intentionally empty: grona-core uses no reflection, JNI or name-based serialization.
# Host R8 keeps the public API through the host's own references; AAPT keeps GronaSlotView
# when inflated from XML. Add only narrowly targeted rules, never package-wide keeps or global options.

That works because of how the SDK is built:

  • No reflection, JNI or name-based serialisation. Nothing in the SDK uses reflection. The one class it names in code, the debug activity, is kept by its manifest entry. So renaming is safe.
  • Your references keep the API. R8 keeps every Grona class and member your code calls, and removes the rest.
  • XML inflation. A GronaSlotView referenced from a layout your app keeps is kept with it. With AGP 8, AAPT generates that keep rule. With AGP 9’s optimised resource shrinking, which is on by default with isShrinkResources, AAPT keep rules are not generated and R8’s own resource analysis is expected to keep the view. Grona has not yet confirmed this on AGP 9. If it fails, use the narrow rule in the note below. Its app:gronaPlacement attribute is a normal resource attribute.
  • R8 full mode. Full mode has been the default since AGP 8.0, and the SDK needs no rules under it.
  • Coroutines. kotlinx-coroutines-android ships its own R8 rules. Do not copy them into your app.
  • No global options. The SDK sets no -dontobfuscate, -dontoptimize or similar options that would change how R8 treats the rest of your app.

grona-debug bundles no consumer rules either. Its activity is declared in its manifest, which keeps it, and it belongs in debug builds only.

Nothing. A standard release configuration works as it is:

app/build.gradle.kts
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}

Do not add -keep class ai.grona.** or similar package-wide rules. They stop R8 removing unused SDK code and hide the real cause of any problem.

In release builds, Grona classes are obfuscated with the rest of your app. Upload your R8 mapping file to your crash reporter, as you do for your own code, to read SDK frames. The SDK never throws into your app on purpose: public calls catch their own errors and log them through your GronaLogger.