Skip to main content

Known Limitations

Please review the following requirements and limitations before using the SDK.

Device Requirements

ItemOpenCL MinimumOpenCL Recommended
Android Version8.0 (API 26)12+ (API 31)
RAM4GB6GB or more
Storage500MB1GB or more
GPUOpenGL ES 2.0 / OpenCL 1.2OpenGL ES 3.0+ / OpenCL 2.0+

Supported Architectures (ABI)

ABISupportedNotes
arm64-v8aSupportedMost modern devices
armeabi-v7aSupportedOlder 32-bit devices
x86_64Not supportedEmulator
x86Not supportedEmulator
Emulator Notice

The SDK does not work on x86/x86_64 emulators.

Testing methods:

  • Use a real Android device (recommended)
  • Use an ARM-based emulator (e.g., default emulator on Apple Silicon Macs)

Network Requirements

Prerequisites

  • Internet connection: Required for real-time WebSocket communication
  • Protocol: HTTPS / WSS (TLS 1.2 or higher)
  • Port: 443

Firewall Configuration

# Domains to allow
*.klleon.io

Network Permissions

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Audio Limitations

USB Microphone Compatibility

  • MMAP policy: MMAP is managed internally by the SDK and is disabled by default. Enabling MMAP may cause stream open failures with some USB microphones.
  • USB device selection: USB microphones are automatically detected and selected when connected.
  • Incompatible devices: On some MediaTek-based TVs, opening audio streams from USB composite devices (e.g., DM30RGB) may fail.

Echo Prevention

  • Voice recognition is automatically blocked during avatar speech.

Known Issues

1. Memory Usage

Memory usage can be high during video processing and AI inference. In particular, calling ResourceManager.init() allocates approximately 1GB of native memory for YUV frame buffers.

Buffer Lifecycle

finish() retains buffers for immediate reuse when re-entering with the same avatar (0ms). For complete memory release, deinit() must be explicitly called.

ScenarioBehavior
Same avatar re-entryinit(same avatarId) -> Buffer reuse (0ms)
Different avatar switchinit(new avatarId) -> Automatically release previous buffer + new allocation
App background transitiononTrimMemory -> deinit() -> Buffer release
App exitCharacterActivity.onDestroy -> deinit() -> Complete release
Process force killOS kernel auto-reclaims (no code needed)

Required Implementation Patterns

Application class -- Automatic background memory release:

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
registerComponentCallbacks(object : ComponentCallbacks2 {
override fun onTrimMemory(level: Int) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
ResourceManager.deinit()
}
}
override fun onConfigurationChanged(newConfig: Configuration) {}
override fun onLowMemory() { ResourceManager.deinit() }
})
}
}

SDK play screen (ChatActivity, etc.):

override fun onDestroy() {
super.onDestroy()
// finish() is a suspend function, so run it in a coroutine
CoroutineScope(Dispatchers.Default).launch {
klleonOndeviceSdk.finish() // Retain buffers (waiting for reuse)
}
}

Avatar selection screen (CharacterActivity, etc.):

override fun onDestroy() {
super.onDestroy()
// Manually release memory if SDK is not playing (exiting before play)
if (!KlleonOndeviceSdk.playing) {
ResourceManager.deinit()
}
}
Safe for Duplicate Calls
  • init(): When called again with the same avatar (avatarId), reuses existing buffer (no duplicate allocation)
  • deinit(): Safe to call multiple times (idempotency guaranteed)
  • finish(): Safe for duplicate calls due to internal playing state check

2. Background Limitations

Video processing is paused when the app transitions to the background.

3. Single Instance Limitation

Only one KlleonOndeviceSdk instance should be created per app. Internal coroutine scopes and thread pools are allocated per instance, so creating multiple instances causes resource conflicts and memory leaks.

Recommended: Manage as an object singleton

// Share a single instance across the entire app
object SdkConfig {
val sdk = KlleonOndeviceSdk()
}

// Use in Activity
class ChatActivity : ComponentActivity() {
private val klleonOndeviceSdk = SdkConfig.sdk // Reuse the same instance
}

class AnotherActivity : ComponentActivity() {
private val klleonOndeviceSdk = SdkConfig.sdk // Reuse the same instance
}
Warning

If you create KlleonOndeviceSdk() directly in an Activity field, a new instance is created each time the Activity is recreated (screen rotation, low memory, etc.), causing thread pools from previous instances to accumulate.

// Incorrect usage - multiple instances
class MainActivity : Activity() {
val sdk1 = KlleonOndeviceSdk() // Instance 1
val sdk2 = KlleonOndeviceSdk() // Instance 2 - conflict!
}

4. Screen Rotation

SDK state may be reset when an Activity is recreated due to screen rotation.

Solution:

<!-- AndroidManifest.xml - Handle screen rotation directly -->
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|screenLayout" />

5. Android TV Specifics

  • On TV platforms, auto-focus is assigned to the first focusable element on layout changes, which may cause the keyboard to appear automatically.
  • Block this at the source with focusProperties { canFocus = false }, then enable only on click.
  • Some MediaTek-based TVs may have compatibility issues with certain USB audio devices.

Performance Optimization Tips

GPU Acceleration

The SDK uses GPU acceleration by default. If issues occur on some low-end devices:

// Check logs when GPU issues occur
adb logcat | grep "Klleon_"

Battery Optimization

Battery consumption can be significant during prolonged use:

  • Call finish() when not in use
  • Recommended to stop processing when the screen is off
  • Utilize standby mode with enterStandby() / exitStandby()

Support

For issues not resolved by the above limitations, please contact us through Klleon Studio.