4. 使用SoundPool播放短音效
任务说明
本案例实现一个Android音效播放器:将多个短音效文件预加载到SoundPool中,界面提供多个按钮,点击不同按钮播放对应音效,同时限制最大音流数以控制系统资源占用。
实现方案
使用SoundPool.Builder创建SoundPool实例,设置最大音流数为3(即最多同时播放3个音效,超出时系统按优先级策略处理)。通过AudioAttributes指定音效用途为USAGE_MEDIA。音效文件放在res/raw目录下,使用load()方法预加载,加载完成后通过setOnLoadCompleteListener确认就绪。播放时调用play()方法并传入音效ID。
代码实现
1. 音效资源准备
在res/raw/目录下放置三个短音效文件:effect_click.wav、effect_notify.wav、effect_success.wav(可自行替换为任意短wav或ogg文件)。
2. 主布局 activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="24dp">
<Button
android:id="@+id/btn_click"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="播放点击音效"
android:textSize="18sp"/>
<Button
android:id="@+id/btn_notify"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="播放通知音效"
android:textSize="18sp"/>
<Button
android:id="@+id/btn_success"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="播放成功音效"
android:textSize="18sp"/>
<TextView
android:id="@+id/tv_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="音效未加载"
android:textSize="14sp"/>
</LinearLayout>
3. MainActivity.java
package com.example.soundpooldemo;
import android.media.AudioAttributes;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private SoundPool soundPool;
private int soundClickId;
private int soundNotifyId;
private int soundSuccessId;
private boolean isLoaded = false;
private TextView tvStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvStatus = findViewById(R.id.tv_status);
Button btnClick = findViewById(R.id.btn_click);
Button btnNotify = findViewById(R.id.btn_notify);
Button btnSuccess = findViewById(R.id.btn_success);
// 创建SoundPool:最大音流数为3
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
soundPool = new SoundPool.Builder()
.setMaxStreams(3)
.setAudioAttributes(audioAttributes)
.build();
// 预加载音效
soundClickId = soundPool.load(this, R.raw.effect_click, 1);
soundNotifyId = soundPool.load(this, R.raw.effect_notify, 1);
soundSuccessId = soundPool.load(this, R.raw.effect_success, 1);
// 监听加载完成
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
if (status == 0) {
isLoaded = true;
tvStatus.setText("音效加载完成,可播放");
} else {
tvStatus.setText("音效加载失败,错误码: " + status);
}
}
});
// 按钮点击播放
btnClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playSound(soundClickId);
}
});
btnNotify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playSound(soundNotifyId);
}
});
btnSuccess.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playSound(soundSuccessId);
}
});
}
private void playSound(int soundId) {
if (!isLoaded) {
tvStatus.setText("音效尚未加载完成,请稍候");
return;
}
// 播放:左音量1.0,右音量1.0,优先级1,循环0次,播放速率1.0
soundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (soundPool != null) {
soundPool.release();
soundPool = null;
}
}
}
关键实现说明
- 最大音流数控制:
setMaxStreams(3)限制同时播放的音效数量。当第4个音效请求播放时,系统会根据优先级和播放时间自动停止一个已有音流。 - 预加载机制:三个音效在
onCreate中通过load()异步加载,加载完成后通过回调通知界面。 - 播放参数:
play()方法中左右声道音量均为1.0,优先级为1,循环次数为0(不循环),播放速率1.0(正常速度)。
验证方法
- 在Android Studio中创建新项目,将上述布局和代码复制到对应文件。
- 在
res/raw/目录下添加三个短音效文件(wav或ogg格式,时长建议不超过3秒)。 - 连接真机或模拟器运行应用,观察界面显示"音效加载完成,可播放"。
- 快速连续点击三个按钮,确认能听到对应音效;快速点击4次以上,观察系统自动停止最早播放的音效(因最大音流数为3),验证最大音流数限制生效。
判定标准:应用启动后状态栏显示加载成功;点击每个按钮都能播放对应音效;连续快速点击多个按钮时,同时播放的音效不超过3个,且无应用崩溃或异常退出。