Skip to main content

Core Classes

AvatarKit

The core management class of the SDK, responsible for initialization and global configuration.
/// SDK entry class
object AvatarKit {
    /// Initialize SDK
    /// @param context - Application context
    /// @param appId - Application ID
    /// @param configuration - SDK configuration
    fun initialize(
        context: Context,
        appId: String,
        configuration: Configuration
    )
    
    /// Session token for WebSocket authentication
    var sessionToken: String
    
    /// SDK version
    val version: String
    
    /// Configuration class
    class Configuration(
        val environment: Environment
    )
    
    /// Environment enum
    enum class Environment(internal val serverUrl: String) {
        CN("api-test.spatialwalk.top"),
        US("api-test.spatialwalk.top"),
        TEST("api-test.spatialwalk.top")
    }
}

AvatarManager

Avatar resource manager, responsible for downloading, caching, and loading avatar data.
object AvatarManager {
    /// Initialize AvatarManager
    /// Must be called before use
    fun initialize(context: Context)
    
    /// Load avatar resource
    /// @param id - Avatar ID
    /// @param onProgress - Progress callback (optional)
    /// @return Avatar - Loaded avatar object
    suspend fun load(
        id: String,
        onProgress: ((LoadProgress) -> Unit)? = null
    ): Avatar
    
    /// Clear all cache
    suspend fun clearCache()
    
    /// Get cache statistics
    suspend fun getCacheStats(): CacheStats
    
    /// Clear cache for specific avatar
    suspend fun clear(id: String)
    
    /// Clear all cache
    suspend fun clearAll()
    
    /// Get cache size for specific avatar
    suspend fun getCacheSize(id: String): Long
    
    /// Get total cache size
    suspend fun getAllCacheSize(): Long
    
    /// Load progress sealed class
    sealed class LoadProgress {
        data class Downloading(val progress: Float) : LoadProgress()
        object Completed : LoadProgress()
        data class Failed(val error: Throwable) : LoadProgress()
    }
    
    /// Cache statistics
    data class CacheStats(
        val totalEntries: Int,
        val totalSizeMB: Long,
        val maxSizeMB: Long
    )
}

AvatarView

3D rendering view that automatically creates and manages AvatarController.
class AvatarView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : SurfaceView(context, attrs, defStyleAttr) {
    
    /// Real-time communication controller
    lateinit var avatarController: AvatarController
        private set
    
    /// Initialize view with avatar
    /// @param avatar - Loaded avatar object
    /// @param scope - Coroutine scope (optional, defaults to lifecycle scope)
    fun init(avatar: Avatar, scope: CoroutineScope? = null)
    
    /// Pause rendering
    /// Should be called in Activity/Fragment onPause()
    fun onPause()
    
    /// Resume rendering
    /// Should be called in Activity/Fragment onResume()
    fun onResume()
    
    /// Clean up all resources
    /// Should be called when no longer in use, releases Vulkan resources
    fun cleanup()
}

AvatarController

Real-time communication controller that handles WebSocket connections and audio/video data.
class AvatarController internal constructor(
    val context: Context,
    val avatar: Avatar,
    val coroutineScope: CoroutineScope
) {
    /// Start WebSocket connection
    fun start()
    
    /// Stop and close connection
    fun stop()
    
    /// Interrupt current conversation
    fun interrupt()
    
    /// Send audio data
    /// @param audioData - Audio data (ByteArray)
    /// @param end - Whether this is the end of audio. false means more audio data, true means audio sending is complete
    fun send(audioData: ByteArray, end: Boolean = false)
    
    /// Mute/unmute audio
    var mute: Boolean
    
    /// Connection state callback
    var onConnectionState: ((ConnectionState) -> Unit)? = null
    
    /// Avatar state callback
    var onAvatarState: ((AvatarPlayer.AvatarState) -> Unit)? = null
    
    /// Error callback
    var onError: ((Throwable) -> Unit)? = null
    
    /// Connection state sealed class
    sealed class ConnectionState {
        object Disconnected : ConnectionState()
        object Connecting : ConnectionState()
        object Connected : ConnectionState()
        data class Failed(val exception: Exception) : ConnectionState()
    }
}

Avatar

Avatar data class containing core avatar information.
class Avatar(
    val id: String,
)

Configuration Types

Configuration

SDK configuration class.
class Configuration(
    val environment: Environment
)

Environment

Environment enum.
enum class Environment(internal val serverUrl: String) {
    /// China region
    CN("api-test.spatialwalk.top"),
    /// US region
    US("api-test.spatialwalk.top"),
    /// Test environment
    TEST("api-test.spatialwalk.top")
}

State Types

ConnectionState

Connection state sealed class.
sealed class ConnectionState {
    object Disconnected : ConnectionState()
    object Connecting : ConnectionState()
    object Connected : ConnectionState()
    data class Failed(val exception: Exception) : ConnectionState()
}

AvatarState

Avatar state enum (from AvatarPlayer).
enum class AvatarState {
    /// Idle state, showing breathing animation
    Idle,
    /// Active, waiting for playable content
    Active,
    /// Playing
    Playing
}

LoadProgress

Load progress sealed class.
sealed class LoadProgress {
    /// Downloading
    data class Downloading(val progress: Float) : LoadProgress()
    /// Completed
    object Completed : LoadProgress()
    /// Failed
    data class Failed(val error: Throwable) : LoadProgress()
}

Usage Examples

Basic Initialization

1

Create Configuration

import ai.spatialwalk.avatarkit.AvatarKit

AvatarKit.initialize(
    context = applicationContext,
    appId = "your-app-id",
    configuration = AvatarKit.Configuration(
        environment = AvatarKit.Environment.CN
    )
)
AvatarKit.sessionToken = "your-session-token"
2

Load Avatar

import ai.spatialwalk.avatarkit.assets.AvatarManager
import kotlinx.coroutines.launch
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

lifecycleScope.launch {
    val avatar = withContext(Dispatchers.IO) {
        AvatarManager.load("avatar-id") { progress ->
            when (progress) {
                is AvatarManager.LoadProgress.Downloading -> {
                    val percent = (progress.progress * 100).toInt()
                    Log.d(TAG, "Loading: $percent%")
                }
                is AvatarManager.LoadProgress.Completed -> {
                    Log.d(TAG, "Avatar loaded")
                }
                is AvatarManager.LoadProgress.Failed -> {
                    Log.e(TAG, "Failed: ${progress.error.message}")
                }
            }
        }
    }
}
Ensure the avatar ID is valid and network connection is normal. It’s recommended to check network status before loading.

Create Avatar View

1

Create View Instance

import ai.spatialwalk.avatarkit.AvatarView

// In XML layout
<ai.spatialwalk.avatarkit.AvatarView
    android:id="@+id/avatar_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

// Or in Compose
AndroidView(
    factory = { context -> AvatarView(context) }
)
2

Initialize and Start

val avatarView = findViewById<AvatarView>(R.id.avatar_view)

// Initialize with avatar
avatarView.init(avatar, lifecycleScope)

// Set up event listeners
avatarView.avatarController.onConnectionState = { state ->
    Log.d(TAG, "Connection state: $state")
}

avatarView.avatarController.onAvatarState = { state ->
    Log.d(TAG, "Avatar state: $state")
}

avatarView.avatarController.onError = { error ->
    Log.e(TAG, "Error: ${error.message}")
}

// Start connection
avatarView.avatarController.start()

Audio Processing

Audio Application Example
// Read audio data from file or stream
val audioData = readAudioFile() // Your audio reading logic

// Send audio data (end=false means more audio data)
avatarView.avatarController.send(audioData, end = false)

// When audio ends, call with end=true
// Only after sending end=true will the server return animation data and start playing
avatarView.avatarController.send(audioData, end = true)

// Alternatively, you can set end=true when sending the last audio chunk
// avatarView.avatarController.send(lastAudioChunk, end = true)

// Interrupt conversation
avatarView.avatarController.interrupt()

Resource Management

Resource Cleanup Example
override fun onPause() {
    super.onPause()
    avatarView.onPause()
}

override fun onResume() {
    super.onResume()
    avatarView.onResume()
}

override fun onDestroy() {
    super.onDestroy()
    lifecycleScope.launch {
        avatarView.avatarController.stop()
        avatarView.cleanup()
    }
}

Error Handling

Error Handling Example
avatarView.avatarController.onError = { error ->
    Log.e(TAG, "AvatarController error: ${error.message}", error)
    // Implement retry logic
}

Cache Management

Cache Management Example
// Get cache statistics
lifecycleScope.launch {
    val stats = AvatarManager.getCacheStats()
    Log.d(TAG, "Cache entries: ${stats.totalEntries}")
    Log.d(TAG, "Cache size: ${stats.totalSizeMB}MB / ${stats.maxSizeMB}MB")
}

// Clear specific avatar cache
lifecycleScope.launch {
    AvatarManager.clear("avatar-id")
}

// Clear all cache
lifecycleScope.launch {
    AvatarManager.clearAll()
}

Performance Optimization Tips

  • SDK automatically manages resource caching, no need to re-download for repeated loads
  • Resources are cached using LRU strategy with automatic cleanup
  • Vulkan rendering backend provides optimal performance on Android devices
  • Support for lifecycle-aware resource management
  • It’s recommended to use on modern Android devices for best performance