Android
Native Android SDK for on-device ML inference
The Android SDK provides native Kotlin bindings to the Xybrid runtime via BoltFFI, enabling on-device ML inference in Android applications.
Installation
Add the Xybrid SDK from Maven Central:
dependencies {
implementation("ai.xybrid:xybrid-kotlin:0.5.0")
}Minimum SDK: 24 (Android 7.0)
Quick Start
import ai.xybrid.*
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Xybrid.init(this)
}
}
// Describe, then explicitly load a model from the registry
val model = Xybrid.model("kokoro-82m").load()
// Run inference
val result = model.runAsync(Envelope.text("Hello, world!"))
if (result.success) {
println("Output: ${result.text}")
println("Latency: ${result.latencyMs}ms")
}Xybrid.init(context) also registers BatteryManager and (on API 29+) PowerManager.OnThermalStatusChangedListener observers, forwarding readings to the routing engine.
Initialization
Inference runs entirely on-device whether or not you authenticate. Pass an apiKey to light up the dashboard — that single call starts the telemetry exporter, and your model.run(...) calls automatically emit execution traces:
Xybrid.init(this, apiKey = BuildConfig.XYBRID_API_KEY)Without a key, telemetry is disabled and the first inference logs a one-shot hint pointing at the dashboard (suppress with the XYBRID_QUIET=1 environment variable). Get a free key at dashboard.xybrid.dev. For a self-hosted dashboard, also pass ingestUrl.
Model Loading
From Registry
val model = Xybrid.model("whisper-tiny-ggml").load()From Local Bundle
val model = Xybrid.model(ModelSource.bundle("/path/to/model.xyb")).load()Xybrid.model(...) creates a cheap, unloaded reference. Use
ModelSource.directory(path) and ModelSource.huggingFace("org/repo") for an
unpacked directory and Hugging Face respectively. Suspending load() is the
explicit boundary that may resolve metadata, download artifacts, access disk,
and initialize the runtime. Use loadBlocking() only from Java or an existing
worker thread.
Input Envelopes
The Envelope factory creates type-safe inputs for different model types.
Audio (Speech Recognition)
val envelope = Envelope.audio(
bytes = audioBytes, // Raw PCM bytes
sampleRate = 16000u, // Sample rate in Hz
channels = 1u // Mono
)
val result = model.run(envelope)
println("Transcription: ${result.text}")Text (Text-to-Speech)
// Simple text
val envelope = Envelope.text("Hello, how are you?")
// With voice and speed
val envelope = Envelope.text("Hello", voiceId = "af_heart", speed = 1.0)
val result = model.run(envelope)
val audioOutput = result.audioBytes // Raw PCM audioEmbedding
val envelope = Envelope.embedding(listOf(0.1f, 0.2f, 0.3f))
val result = model.run(envelope)
val vector = result.embeddingResult Handling
val result = model.run(envelope)
if (result.success) {
when (result.outputType) {
"text" -> println("Text: ${result.text}")
"audio" -> playAudio(result.audioBytes!!)
"embedding" -> process(result.embedding!!)
}
println("Latency: ${result.latencyMs}ms")
println("Latency: ${result.latencySeconds}s")
} else {
println("Error: ${result.error}")
}XybridResult Properties
| Property | Type | Description |
|---|---|---|
success | Boolean | Whether inference succeeded |
error | String? | Error message if failed |
outputType | String | "text", "audio", or "embedding" |
text | String? | Text output (ASR, LLM) |
audioBytes | ByteArray? | Audio output (TTS) |
embedding | List<Float>? | Embedding vector |
latencyMs | UInt | Inference latency in ms |
isFailure | Boolean | Convenience: !success |
latencySeconds | Double | Latency in seconds |
Error Handling
The SDK uses sealed exception classes for type-safe error handling:
try {
val model = Xybrid.model("kokoro-82m").load()
val result = model.runAsync(envelope)
} catch (e: XybridException.ModelNotFound) {
println("Model not found: ${e.modelId}")
} catch (e: XybridException.InferenceFailed) {
println("Inference failed: ${e.message}")
} catch (e: XybridException.InvalidInput) {
println("Invalid input: ${e.message}")
} catch (e: XybridException.IoException) {
println("I/O error: ${e.message}")
} catch (e: XybridException) {
// Catch-all with user-friendly message
showError(e.displayMessage)
}Platform Support
| Architecture | Status |
|---|---|
| arm64-v8a | Supported |
| armeabi-v7a | Supported |
| x86_64 | Supported (emulator) |