본문으로 건너뛰기

알려진 제한사항

SDK 사용 전 아래 요구사항과 제한사항을 확인하세요.

디바이스 요구사항

항목OpenCL 최소OpenCL 권장
Android 버전8.0 (API 26)12+ (API 31)
RAM4GB6GB 이상
저장공간500MB1GB 이상
GPUOpenGL ES 2.0 / OpenCL 1.2OpenGL ES 3.0+ / OpenCL 2.0+

지원 아키텍처 (ABI)

ABI지원 여부비고
arm64-v8a지원대부분의 최신 디바이스
armeabi-v7a지원구형 32비트 디바이스
x86_64미지원에뮬레이터
x86미지원에뮬레이터
에뮬레이터 주의사항

x86/x86_64 에뮬레이터에서는 SDK가 동작하지 않습니다.

테스트 방법:

  • 실제 Android 디바이스 사용 (권장)
  • ARM 기반 에뮬레이터 사용 (예: Apple Silicon Mac의 기본 에뮬레이터)

네트워크 요구사항

필수 조건

  • 인터넷 연결: 실시간 WebSocket 통신을 위해 필수
  • 프로토콜: HTTPS / WSS (TLS 1.2 이상)
  • 포트: 443

방화벽 설정

# 허용해야 할 도메인
*.klleon.io

네트워크 권한

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

오디오 관련 제한사항

USB 마이크 호환성

  • MMAP 정책: MMAP은 SDK 내부에서 관리되며 기본 비활성화입니다. MMAP 활성화 시 일부 USB 마이크에서 스트림 열기 실패가 발생할 수 있습니다.
  • USB 장치 선택: USB 마이크가 연결되면 자동으로 감지되어 선택됩니다.
  • 호환되지 않는 디바이스: 일부 MediaTek 기반 TV에서 USB 복합 장치(예: DM30RGB)의 오디오 스트림 열기가 실패할 수 있습니다.

에코 방지

  • 아바타 발화 중에는 음성 인식이 자동 차단됩니다.

알려진 이슈

1. 메모리 사용량

비디오 처리 및 AI 추론 중 메모리 사용량이 높을 수 있습니다. 특히 ResourceManager.init() 호출 시 YUV 프레임 버퍼로 약 1GB의 네이티브 메모리가 할당됩니다.

버퍼 lifecycle

finish()는 버퍼를 유지하여 동일 아바타 재진입 시 즉시 재사용합니다 (0ms). 완전한 메모리 해제는 deinit()을 명시적으로 호출해야 합니다.

시나리오동작
같은 아바타 재진입init(동일 avatarId) → 버퍼 재사용 (0ms)
다른 아바타 전환init(새 avatarId) → 자동으로 이전 버퍼 해제 + 새 할당
앱 백그라운드 전환onTrimMemorydeinit() → 버퍼 해제
앱 종료CharacterActivity.onDestroydeinit() → 완전 해제
프로세스 강제종료OS 커널이 자동 회수 (코드 불필요)

필수 구현 패턴

Application 클래스 — 백그라운드 메모리 자동 해제:

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 화면 (ChatActivity 등):

override fun onDestroy() {
super.onDestroy()
// finish()는 suspend 함수이므로 코루틴에서 실행
CoroutineScope(Dispatchers.Default).launch {
klleonOndeviceSdk.finish() // 버퍼 유지 (재사용 대기)
}
}

아바타 선택 화면 (CharacterActivity 등):

override fun onDestroy() {
super.onDestroy()
// SDK가 재생 중이 아니면 (play 전 이탈) 수동으로 메모리 해제
if (!KlleonOndeviceSdk.playing) {
ResourceManager.deinit()
}
}
중복 호출 안전
  • init(): 동일 아바타(avatarId) 재호출 시 기존 버퍼를 재사용 (중복 할당 없음)
  • deinit(): 여러 번 호출해도 안전 (멱등성 보장)
  • finish(): 내부 playing 상태 체크로 중복 호출 안전

2. 백그라운드 제한

앱이 백그라운드로 전환되면 비디오 처리가 일시 중지됩니다.

3. 단일 인스턴스 제한

KlleonOndeviceSdk 인스턴스는 앱당 하나만 생성해야 합니다. 내부 코루틴 스코프와 스레드풀이 인스턴스별로 할당되므로, 여러 인스턴스를 생성하면 리소스 충돌 및 메모리 누수가 발생합니다.

권장: object 싱글톤으로 관리

// 앱 전역에서 단일 인스턴스를 공유
object SdkConfig {
val sdk = KlleonOndeviceSdk()
}

// Activity에서 사용
class ChatActivity : ComponentActivity() {
private val klleonOndeviceSdk = SdkConfig.sdk // 동일 인스턴스 재사용
}

class AnotherActivity : ComponentActivity() {
private val klleonOndeviceSdk = SdkConfig.sdk // 동일 인스턴스 재사용
}
주의

Activity 필드에서 KlleonOndeviceSdk()를 직접 생성하면, Activity 재생성(화면 회전, 메모리 부족 등) 시마다 새 인스턴스가 만들어져 이전 인스턴스의 스레드풀이 누적됩니다.

// 잘못된 사용법 - 여러 인스턴스
class MainActivity : Activity() {
val sdk1 = KlleonOndeviceSdk() // 인스턴스 1
val sdk2 = KlleonOndeviceSdk() // 인스턴스 2 - 충돌 발생!
}

4. 화면 회전

화면 회전 시 Activity가 재생성되면 SDK 상태가 초기화될 수 있습니다.

해결 방법:

<!-- AndroidManifest.xml - 화면 회전 직접 처리 -->
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|screenLayout" />

5. Android TV 특이사항

  • TV 플랫폼에서 레이아웃 변경 시 자동 포커스가 첫 번째 focusable 요소에 부여되어 키보드가 자동 표시될 수 있습니다.
  • focusProperties { canFocus = false } 로 원천 차단 후, 클릭 시에만 활성화하세요.
  • MediaTek 기반 TV에서 일부 USB 오디오 장치 호환성 문제가 있을 수 있습니다.

성능 최적화 팁

GPU 가속

SDK는 기본적으로 GPU 가속을 사용합니다. 일부 저사양 디바이스에서 문제 발생 시:

// GPU 문제 발생 시 로그 확인
adb logcat | grep "Klleon_"

배터리 최적화

장시간 사용 시 배터리 소모가 클 수 있습니다:

  • 사용하지 않을 때 finish() 호출
  • 화면 꺼짐 시 처리 중지 권장
  • enterStandby() / exitStandby()로 대기화면 모드 활용

지원 문의

위 제한사항으로 해결되지 않는 문제는 Klleon Studio를 통해 문의해 주세요.