Prerequisites
- An existing Android app using Gradle, Kotlin, or Java.
- The Ailoha CLI installed: see install instructions.
- An emulator or physical device with
adbavailable when connecting from the host.
1. Add the packages
Use the real agent only in debug builds and the no-op artifact in release builds:
dependencies {
debugImplementation("com.ailoha:ailoha-android-agent:$ailohaVersion")
debugImplementation("com.ailoha:ailoha-android-agent-compose:$ailohaVersion")
debugImplementation("com.ailoha:ailoha-android-agent-okhttp:$ailohaVersion")
debugImplementation("com.ailoha:ailoha-android-agent-timber:$ailohaVersion")
releaseImplementation("com.ailoha:ailoha-android-agent-noop:$ailohaVersion")
}
Preview packages publish to GitHub Packages Maven. Release packages publish to Maven Central once the repository release workflow is configured for signing and Central Portal credentials.
2. Start the agent
Start in debug-only application code. A debug source-set Application class is the safest option because release builds never reference the server artifact:
class App : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
AilohaAndroidAgent.start(
application = this,
options = AilohaAgentOptions(appName = "My Android App")
)
}
}
}
The server binds to loopback on 9233 and falls back through 9238. It registers the selected port with the Ailoha broker on 19323.
3. Enable Compose semantics (optional)
For Jetpack Compose, install the optional provider after starting the core agent:
if (BuildConfig.DEBUG) {
AilohaAndroidAgent.start(this)
AilohaComposeAgent.install()
}
The Compose provider maps semantics nodes into the protocol tree and uses Modifier.testTag("...") as automationId.
4. Add diagnostics adapters (optional)
Android has many logging and HTTP stacks, so generic capture is app opt-in. For OkHttp and Timber:
val client = OkHttpClient.Builder()
.addInterceptor(AilohaOkHttpInterceptor())
.build()
Timber.plant(AilohaTimberTree())
Apps can also call AilohaAndroidAgent.recordNetworkRequest(...), recordLog(...), and mark(...) directly.
5. Use stable IDs
For Android Views, resource IDs are stable and become protocol automation IDs. You can also set an explicit Ailoha tag:
binding.loginButton.setAilohaAutomationId("LoginButton")
For Compose:
Button(
modifier = Modifier.testTag("LoginButton"),
onClick = ::signIn
) { Text("Sign in") }
6. Run and verify
Launch the app in debug mode, forward the port, then query the agent:
adb forward tcp:9233 tcp:9233
ailoha agent status
ailoha ui tree --depth 2
ailoha ui screenshot --output ./android-shot.png
Limitations
- Secure storage, BLE, and generic device jobs return explicit unsupported responses unless a future adapter is added.
- Network and log capture require an adapter or direct calls into the agent API.
- WebSocket streams are not advertised by the Android agent yet; use the REST log, network, and profiler endpoints.
- Never enable the agent in production builds. Use debug source sets,
debugImplementation, and the no-op release artifact.
What's next
- See the protocol capabilities available from the CLI.
- Add a custom extension from your own Android library.