You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手求Android Kotlin中SoundPool.Builder的分步使用讲解

SoundPool 短音效播放分步实现方案(Kotlin Android)

一、核心变量声明

SoundPool 专为短音效设计,音频提前加载进内存,播放延迟极低。在需要用到音效的 Activity 类顶部(onCreate 方法前)声明如下变量:

// 最大同时播放的音频数量,当前场景最多同时播2个音效,设为2即可
private val maxStreams = 2
// 音频采样质量,默认传0即可,官方暂无其他取值定义
private val srcQuality = 0
private lateinit var soundPool: SoundPool
// 存储加载完成的两个音效资源ID
private var winSoundId: Int = 0
private var correctSoundId: Int = 0
// 音频加载完成标记,避免未加载完成就触发播放导致报错
private var isSoundLoaded = false

二、初始化SoundPool并加载音频

在 Activity 的 onCreate 方法中完成初始化和资源加载,兼容高低版本系统:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 初始化SoundPool
    soundPool = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // 5.0及以上系统用Builder构造
        val audioAttributes = AudioAttributes.Builder()
            // 设置音频类型为媒体流,和系统媒体音量档位同步
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()
        SoundPool.Builder()
            .setMaxStreams(maxStreams)
            .setAudioAttributes(audioAttributes)
            .build()
    } else {
        // 5.0以下系统用旧构造方法
        SoundPool(maxStreams, AudioManager.STREAM_MUSIC, srcQuality)
    }

    // 监听音频加载完成事件
    soundPool.setOnLoadCompleteListener { _, _, _ ->
        isSoundLoaded = true
    }

    // 加载raw文件夹下的音频资源,第二个参数为优先级,默认传1即可
    // 注意R.raw后面跟的是你存的wav文件名,全小写,不要加.wav后缀
    winSoundId = soundPool.load(this, R.raw.你的胜利音效文件名, 1)
    correctSoundId = soundPool.load(this, R.raw.你的答题正确音效文件名, 1)
}

三、封装通用播放方法

统一封装播放逻辑,避免重复代码:

private fun playSound(soundId: Int) {
    // 未加载完成或资源ID无效直接返回
    if (!isSoundLoaded || soundId == 0) return
    // 获取系统当前媒体音量,同步系统音量档位
    val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
    val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
    val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
    val volume = currentVolume.toFloat() / maxVolume
    // 播放参数:音频ID、左声道音量、右声道音量、优先级、循环次数(0不循环/-1无限循环)、播放速率(1为正常,取值0.5-2)
    soundPool.play(soundId, volume, volume, 1, 0, 1f)
}

四、对应场景触发播放

  1. 胜利Activity进入时播放:在胜利Activity的onStart方法中调用playSound(winSoundId)即可,onStart阶段音频基本加载完成,不会出现加载未完成的问题。
  2. 答题正确时播放:直接在playCard方法的答题正确逻辑分支中,调用playSound(correctSoundId)即可。

五、资源释放避免内存泄漏

在 Activity 的 onDestroy 方法中释放 SoundPool 占用的资源:

override fun onDestroy() {
    super.onDestroy()
    soundPool.release()
}

注意事项

  • SoundPool 适合1M以内的短音效,音频文件过大会导致加载失败、卡顿
  • 如果两个页面都需要用到音效,可以把上述逻辑封装成单例工具类,不需要每个页面重复初始化
  • 播放无声音时优先检查:文件名是否全小写、是否加了后缀、raw文件夹是否在res根目录、设备媒体音量是否开启

内容的提问来源于stack exchange,提问作者Noccis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:09:03