Android编程权威指南(第二版)学习笔记(十九)—— 第19章 使用 SoundPool 播放音频

既然音频资源文件已准备就绪,现在就来学习如何播放这些.wav音频文件。Android的大部分音频API都比较低级,掌握它们不是那么容易。不过没关系,针对BeatBox应用,可以使用SoundPool这个特别定制的实用工具。 SoundPool能加载一批声音资源到内存中,并支持同时播放多个音频文件。

GitHub 地址:
完成第19章

1. 创建 SoundPool

在 Lollipop 中引入了新的方式创建SoundPool:使用SoundPool.Builder。不过,为了兼容API 16 最低级别,只能选择使用SoundPool(int, int, int)这个老构造方法了。一个代码示例如下:

if (Build.VERSION.SDK_INT >= 21) {
    mSoundPool = new SoundPool.Builder()
            .setMaxStreams(MAX_SOUNDS)
            .setAudioAttributes(new AudioAttributes.Builder()
                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                    .build())
            .build();
} else {
    // This old constructor is deprecated, but we need it for
    // compatibility.
    mSoundPool = new SoundPool(MAX_SOUNDS, AudioManager.STREAM_MUSIC, 0);
}

对于老的 API 来说,

  • 第一个参数指定同时播放多少个音频。这里指定了5个。在播放5个音频时,如果尝试再播放 第6个,SoundPool会停止播放原来的音频。
  • 第二个参数确定音频流类型。Android有很多不同的音频流,它们都有各自独立的音量控制 选项。这就是调低音乐音量,闹钟音量却不受影响的原因。打开文档,查看AudioManager类的 AUDIO_*常量,还可以看到其他控制选项。STREAM_MUSIC使用的是同音乐和游戏一样的音量控制。
  • 最后一个参数指定采样率转换品质。参考文档说这个参数不起作用,所以这里传入0值。

2. 加载音频文件

对于 SoundPool,加载音频文件时在播放前必须预先加载音频。SoundPool加载的音频文件都有自己的Integer类型ID。所以要在Sound类中添加mSoundId实例变量,并添加相应的Getter 和 Setter 方法管理这些ID。

加载一个声音,我们用的是 SoundPool 的 public int load(AssetFileDescriptor afd, int priority) 方法,这个方法需要一个 AssetFileDescriptor 对象和一个整型的 priority(暂时没用,建议设为1)。

AssetFileDescriptor 对象使用 AssetManager 的 openFd() 方法获取,传入的参数是音频文件的 Asset 路径。

所以整个加载的方法就是这么写的:

// BeatBox.java
private void load(Sound sound) throws IOException {
    AssetFileDescriptor afd = mAssets.openFd(sound.getAssetPath());
    int soundId = mSoundPool.load(afd, 1);
    sound.setSoundId(soundId);
}

然后在添加 Sound 列表的时候,一一加载每个声音。

3. 播放音频

添加这样的一个播放方法和释放方法

public void play(Sound sound) {
    Integer soundId = sound.getSoundId();
    // Id 设置成 Integer 类就是为了判断 null 较为方便
    if (soundId == null) {
        return; 
    }
    // play 函数的第一个参数是 sound 的 soundId
    // 应该是由 load() 方法返回的 id
    // 第二个是左声道的音量
    // 第三个是右声道的音量
    // 第四个是priority(无效)
    // 第五个是是否循环
    // 第六个是播放速度
    mSoundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
}

public void release() {
    mSoundPool.release();
}

在点击 ViewHolder 的时候播放,在 onDestroy 的时候释放即可

4.设备旋转和对象保存

使用 retainInstance() 即可


GitHub Page: kniost.github.io
:http://www.jianshu.com/u/723da691aa42

你可能感兴趣的:(Android编程权威指南(第二版)学习笔记(十九)—— 第19章 使用 SoundPool 播放音频)