如何在Android Studio中循环遍历二进制串播放对应20ms音频
问题根因
- 你写的for循环直接连续调用
MediaPlayer.start(),该方法是异步执行的,不会阻塞线程等待音频播放完成,相当于所有比特对应的音频播放指令会在几毫秒内全部触发,自然会出现播放顺序混乱、音频重叠的问题 - 你将
setOnCompletionListener监听设置放在了for循环执行之后,调用start()时监听还未挂载,且播放完成后直接执行release()释放资源,后续要复用同一个MediaPlayer实例播放时会直接报错 - 20ms属于极短音频,MediaPlayer本身的启动、加载延迟较高,并不适配这类短音频高频连续播放的场景,更推荐使用SoundPool实现
修复后实现代码
import android.media.AudioAttributes; import android.media.SoundPool; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private SoundPool soundPool; private int sound1200; private int sound1600; private String binString = "011100101010111010101011101000"; private int currentIndex = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化SoundPool AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(); soundPool = new SoundPool.Builder() .setMaxStreams(1) // 同时只允许1个音频流播放,避免重叠 .setAudioAttributes(audioAttributes) .build(); // 加载两个音频文件 sound1200 = soundPool.load(this, R.raw.wave1200hz, 1); sound1600 = soundPool.load(this, R.raw.wave1600hz, 1); // 音频加载完成监听,加载完成后开始播放 soundPool.setOnLoadCompleteListener((soundPool, sampleId, status) -> { if (currentIndex == 0) { playNextBit(); } }); } private void playNextBit() { if (currentIndex >= binString.length()) { // 所有比特播放完成,释放资源 soundPool.release(); soundPool = null; return; } char bit = binString.charAt(currentIndex); int soundId = bit == '0' ? sound1200 : sound1600; // 播放当前比特对应的音频 soundPool.play(soundId, 1, 1, 1, 0, 1.0f); currentIndex++; // 20ms后播放下一个比特,和音频时长对齐 getWindow().getDecorView().postDelayed(this::playNextBit, 20); } // 页面销毁时释放资源,避免内存泄漏 @Override protected void onDestroy() { super.onDestroy(); if (soundPool != null) { soundPool.release(); soundPool = null; } } }
代码逻辑说明
- 用SoundPool提前加载两个短音频,启动延迟远低于MediaPlayer,适配短音频高频播放场景
- 设置
setMaxStreams(1)保证同一时间只有一个音频播放,不会出现重叠 - 采用递归+延迟调用的方式,每播放完一个20ms音频后再处理下一个比特位,严格保证播放顺序
- 增加了资源释放逻辑,避免内存泄漏
内容的提问来源于stack exchange,提问作者iwrestledthebeartwice
相关产品推荐
相关产品推荐

