新手求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) }
四、对应场景触发播放
- 胜利Activity进入时播放:在胜利Activity的
onStart方法中调用playSound(winSoundId)即可,onStart阶段音频基本加载完成,不会出现加载未完成的问题。 - 答题正确时播放:直接在
playCard方法的答题正确逻辑分支中,调用playSound(correctSoundId)即可。
五、资源释放避免内存泄漏
在 Activity 的 onDestroy 方法中释放 SoundPool 占用的资源:
override fun onDestroy() { super.onDestroy() soundPool.release() }
注意事项
- SoundPool 适合1M以内的短音效,音频文件过大会导致加载失败、卡顿
- 如果两个页面都需要用到音效,可以把上述逻辑封装成单例工具类,不需要每个页面重复初始化
- 播放无声音时优先检查:文件名是否全小写、是否加了后缀、raw文件夹是否在res根目录、设备媒体音量是否开启
内容的提问来源于stack exchange,提问作者Noccis
相关产品推荐
相关产品推荐

