Android Media Player重复播放无法停止问题求助
Hey there! I see the issue you're facing—every time you tap the play button, a new MediaPlayer instance gets created, which means multiple instances are playing the audio at the same time. Your stop button only controls the last instance you created, so the older ones keep running in the background. Let's fix this step by step.
Why This Happens
In your current code, you initialize a new MediaPlayer every time the play button is clicked:
mPlayer = new MediaPlayer();
This leaves all previous MediaPlayer instances active and playing, with no way to stop them since your mPlayer variable now points only to the latest one.
Solution: Reuse & Manage the MediaPlayer Instance
Here's the revised code that fixes the problem by reusing the same MediaPlayer instance and properly managing its state:
MediaPlayer mPlayer; Button playbtn; Button stopbtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); // Replace with your actual layout ID playbtn = findViewById(R.id.play); stopbtn = findViewById(R.id.stop); // Play Button Click Listener playbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Handle existing MediaPlayer instance first if (mPlayer != null) { if (mPlayer.isPlaying()) { mPlayer.stop(); // Stop current ongoing playback } mPlayer.reset(); // Reset to prepare for new data source } else { // Create new instance only if it doesn't exist yet mPlayer = new MediaPlayer(); mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); } Uri myUri1 = Uri.parse("file:///sdcard/Birds/parrot.mp3"); try { mPlayer.setDataSource(getApplicationContext(), myUri1); mPlayer.prepare(); mPlayer.start(); // Start playback } catch (IllegalArgumentException | SecurityException | IllegalStateException | IOException e) { Toast.makeText(getApplicationContext(), "Failed to load audio file!", Toast.LENGTH_LONG).show(); e.printStackTrace(); } } }); // Stop Button Click Listener stopbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mPlayer != null && mPlayer.isPlaying()) { mPlayer.stop(); mPlayer.reset(); // Reset to ready state for next playback // Optional: If you won't play audio again soon, release the instance to save resources // mPlayer.release(); // mPlayer = null; } } }); } // Release MediaPlayer when Activity is destroyed to avoid memory leaks @Override protected void onDestroy() { super.onDestroy(); if (mPlayer != null) { mPlayer.release(); mPlayer = null; } }
Key Improvements
- Reuse the same
MediaPlayerinstance: We only create a new instance ifmPlayeris null. For subsequent clicks, we stop any ongoing playback, reset the instance, and re-prepare the audio. - Proper state management:
reset()puts theMediaPlayerback into an idle state, allowing us to set a new data source (even if it's the same file). - Memory leak prevention: We release the
MediaPlayerinonDestroy()to free up system resources when the Activity is no longer in use. - Cleaner error handling: Combined multiple exception types into a single catch block for readability, and updated the toast message to be more specific for debugging.
Additional Notes
- Storage Permissions: If your app targets Android 6.0 (API level 23) or higher, you'll need to request the
READ_EXTERNAL_STORAGEpermission dynamically to access files on the SD card.
内容的提问来源于stack exchange,提问作者Tahmid

