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

Android中使用SoundPool播放新声音时停止所有先前声音的解决方案——钢琴应用多音同时播放问题

解决Android SoundPool多音频同时播放的问题

嘿,我来帮你搞定这个钢琴应用的声音冲突问题!你之前尝试用soundpool.stop(streamID)没生效,核心原因是没有记录当前正在播放的音频流ID——你每次调用play()都会生成一个新的streamID,但你没保存它,自然不知道该停哪个音频。

下面是具体的解决步骤和修改后的完整代码:

关键修改点

  • 添加一个成员变量currentStreamId,用来保存当前正在播放的音频流ID,初始值设为-1(表示无音频在播放)
  • 每次点击按键播放新音频前,先检查currentStreamId是否有效,若有效则停止该音频
  • 播放新音频后,更新currentStreamId为新的返回值
  • 可选优化:把SoundPool的最大流数设为1,因为我们只需要同时播放一个声音,更符合需求

修改后的完整代码

public class MainActivity extends AppCompatActivity { 
    private Button a,b,c,d,e,f,g; 
    private SoundPool soundPool; 
    private int sound_a,sound_b,sound_c,sound_d,sound_e,sound_f,sound_g;
    // 新增:保存当前播放的音频流ID
    private int currentStreamId = -1; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        a = findViewById(R.id.a); 
        b = findViewById(R.id.b); 
        c = findViewById(R.id.c); 
        d = findViewById(R.id.d); 
        e = findViewById(R.id.e); 
        f = findViewById(R.id.f); 
        g = findViewById(R.id.g); 

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
            // 优化:把最大流数设为1
            soundPool = new SoundPool.Builder().setMaxStreams(1).build(); 
        }else { 
            soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC,0); 
        } 

        sound_a = soundPool.load(this,R.raw.a3,1); 
        sound_b = soundPool.load(this,R.raw.b3,1); 
        sound_c = soundPool.load(this,R.raw.c3,1); 
        sound_d = soundPool.load(this,R.raw.d3,1); 
        sound_e = soundPool.load(this,R.raw.e3,1); 
        sound_f = soundPool.load(this,R.raw.f3,1); 
        sound_g = soundPool.load(this,R.raw.g3,1); 

        a.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                // 停止当前播放的音频(如果有)
                if (currentStreamId != -1) {
                    soundPool.stop(currentStreamId);
                }
                // 播放新音频并更新streamID
                currentStreamId = soundPool.play(sound_a,1,1,0,0,1); 
            } 
        }); 

        b.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                if (currentStreamId != -1) {
                    soundPool.stop(currentStreamId);
                }
                currentStreamId = soundPool.play(sound_b,1,1,0,0,1); 
            } 
        }); 

        c.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                if (currentStreamId != -1) {
                    soundPool.stop(currentStreamId);
                }
                currentStreamId = soundPool.play(sound_c,1,1,0,0,1); 
            } 
        }); 

        d.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                if (currentStreamId != -1) {
                    soundPool.stop(currentStreamId);
                }
                currentStreamId = soundPool.play(sound_d,1,1,0,0,1); 
            } 
        }); 

        e.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                if (currentStreamId != -1) {
                    soundPool.stop(currentStreamId);
                }
                currentStreamId = soundPool.play(sound_e,1,1,0,0,1); 
            } 
        }); 

        f.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                if (currentStreamId != -1) {
                    soundPool.stop(currentStreamId);
                }
                currentStreamId = soundPool.play(sound_f,1,1,0,0,1); 
            } 
        }); 

        g.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                if (currentStreamId != -1) {
                    soundPool.stop(currentStreamId);
                }
                currentStreamId = soundPool.play(sound_g,1,1,0,0,1); 
            } 
        }); 
    } 

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 释放SoundPool资源,避免内存泄漏
        if (soundPool != null) {
            soundPool.release();
            soundPool = null;
        }
    }
}

额外说明

  • soundPool.play()方法返回的streamID是当前音频播放的唯一标识,只有用这个ID调用stop()才能精准停止对应的音频
  • 在onDestroy()里添加soundPool.release()是个好习惯,可以避免内存泄漏
  • 把最大流数设为1后,SoundPool本身也会限制同时播放的音频数量,双重保障避免多音同时播放

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:02:40