Android bindings provide a Kotlin API for GenieX using a JNI bridge pattern with 4 layers:
┌─────────────────────────────────────────────────────────┐
│ Layer 4: Public API (Kotlin) │
│ ModelWrapper.kt - Coroutine-based high-level API │
│ (LlmWrapper, VlmWrapper) │
└────────────────┬────────────────────────────────────────┘
│ calls
┌────────────────▼────────────────────────────────────────┐
│ Layer 3: JNI Interface (Kotlin) │
│ Model.kt - Declares external native methods │
│ (Llm, Vlm) │
└────────────────┬────────────────────────────────────────┘
│ JNI boundary
┌────────────────▼────────────────────────────────────────┐
│ Layer 2: JNI Bridge (C++) │
│ model_bridge_jni.cpp - Implements JNI methods │
│ Java_com_geniex_sdk_jni_Model_* functions │
└────────────────┬────────────────────────────────────────┘
│ calls C API
┌────────────────▼────────────────────────────────────────┐
│ Layer 1: Core Library (C) │
│ libgeniex.so - Provides ml_* API from ml.h │
│ (ml_llm_create, ml_llm_generate, etc.) │
└─────────────────────────────────────────────────────────┘
Each AI capability (LLM, VLM) follows this pattern:
- Path:
app/src/main/java/com/geniex/sdk/LlmWrapper.kt - Purpose: High-level Kotlin API with coroutine support
- Features: Builder pattern, Flow-based streaming, lifecycle management
- Usage:
LlmWrapper.builder().llmCreateInput(...).build()
- Path:
app/src/main/java/com/geniex/sdk/jni/Llm.kt - Purpose: Internal class declaring native JNI methods
- Methods:
external fun create(llmCreateInputObj: LlmCreateInput): Long external fun destroy(handle: Long) external fun generate(handle: Long, prompt: String, config: GenerationConfig, cb: LLMTokenCallback): LlmGenerateResult external fun stopStream(handle: Long) external fun applyChatTemplate(handle: Long, messages: Array<ChatMessage>, tools: String?, enableThinking: Boolean): LlmApplyChatTemplateOutput
- Path:
app/src/main/cpp/llm_bridge_jni.cpp - Purpose: Implements JNI methods, converts Java/Kotlin types to C types
- JNI Functions:
Java_com_geniex_sdk_jni_Llm_create→ callsml_llm_create()Java_com_geniex_sdk_jni_Llm_destroy→ callsml_llm_destroy()Java_com_geniex_sdk_jni_Llm_generate→ callsml_llm_generate()Java_com_geniex_sdk_jni_Llm_stopStream→ manages stop flagsJava_com_geniex_sdk_jni_Llm_applyChatTemplate→ callsml_llm_apply_chat_template()
- Path:
../../../build-android/out/libgeniex.so - API Header:
../../../include/ml.h - Purpose: C API providing mlllm* functions
- Built from:
../../../src/*.cpp(llm.cpp, vlm.cpp, etc.)
| Component | Wrapper | JNI Interface | JNI Bridge | Core API |
|---|---|---|---|---|
| Vision-Language | VlmWrapper.kt | Vlm.kt | vlm_bridge_jni.cpp | mlvlm* |
- Build Script:
../../../build_android.sh - CMake Entry:
app/src/main/cpp/CMakeLists.txt - Output:
libnpu_jni.so(JNI bridge wrapper loaded by GenieXSdk.kt)libgeniex.so(core ML library linked by JNI wrapper)- Plugin libraries:
libgeniex_plugin.so(NPU backend for NPU acceleration)
- GenieXSdk.kt: Initializes SDK and loads native libraries
init { System.loadLibrary("npu_jni") // Loads Layer 2 JNI bridge }
- NPU Backend: Provides NPU acceleration for Qualcomm Snapdragon (using QNN library internally)
- Path:
../../../build-android/out/npu/ - Registration:
GenieXSdk.init()callsregisterPlugin()to dynamically load plugin libraries
bindings/android/
├── app/
│ ├── src/main/
│ │ ├── cpp/ # Layer 2: JNI Bridge (C++)
│ │ │ ├── llm_bridge_jni.cpp
│ │ │ ├── vlm_bridge_jni.cpp
│ │ │ ├── geniex_sdk.cpp # SDK initialization & plugin registration
│ │ │ ├── jniutils.cpp/.h # JNI type conversion utilities
│ │ │ ├── jni_cb.cpp/.h # Callback handling for streaming
│ │ │ ├── qnn/CMakeLists.txt # NPU backend build config (QNN library)
│ │ │ └── CMakeLists.txt
│ │ └── java/com/geniex/sdk/
│ │ ├── jni/ # Layer 3: JNI Interface (Kotlin)
│ │ │ ├── Llm.kt
│ │ │ └── Vlm.kt
│ │ ├── LlmWrapper.kt # Layer 4: Public API
│ │ ├── VlmWrapper.kt
│ │ ├── GenieXSdk.kt # SDK entry point
│ │ └── bean/ # Data classes
│ └── build.gradle.kts # Build configuration
└── README.md # This file
../../include/ml.h # Layer 1: Core C API header
../../src/*.cpp # Layer 1: Core implementation
../../build-android/out/
├── libgeniex.so # Layer 1: Core library
└── npu/ # NPU plugin libraries (QNN-based)
└── libgeniex_plugin.so
Generating the repo folder in maven format.
Under GenieX-bridge/bindings/android:
- Modify
tmpVersioninapp/update.gradleto the new version. - Sync project with Gradle files.
- Execute
./gradlew assembleRelease. - Execute
./gradlew publishto obtain therepofolder.
TODO: document the Maven Central publishing procedure.
TODO: document the GitHub-based Android artifact publishing instructions.
SDK logs are routed to logcat under the tag GenieXSdk at the corresponding
Android priority (VERBOSE/DEBUG/INFO/WARN/ERROR). Filter from your
app via the standard logcat tooling:
adb logcat -s GenieXSdk