Android Studio音乐App开发问题:切换歌曲时停止前一曲播放
嗨,这个问题我之前做音乐App的时候也碰到过!核心原因就是每次打开播放页面(新Activity)都会创建一个全新的播放器实例,之前的播放页面并没有被彻底销毁或者播放器没被停止,导致多个播放器同时在后台工作。下面给你几个实用的解决方案,你可以根据App的复杂度选择:
解决方案1:使用单例模式统一管理播放器
这种方式能保证整个App里只有一个播放器实例,切换歌曲时自动停止之前的播放,非常适合小型音乐App。
先创建一个单例的播放器工具类:
package com.recycler.hp.navigationbar; import android.media.MediaPlayer; import android.net.Uri; import android.content.Context; public class MediaPlayerHelper { // 单例实例 private static MediaPlayerHelper instance; private MediaPlayer mediaPlayer; // 私有构造方法,禁止外部创建实例 private MediaPlayerHelper() {} // 获取单例的方法 public static synchronized MediaPlayerHelper getInstance() { if (instance == null) { instance = new MediaPlayerHelper(); } return instance; } // 播放/切换歌曲的方法 public void playSong(Context context, Uri songUri) { try { // 如果已有播放器,先停止并释放 if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } mediaPlayer.release(); mediaPlayer = null; } // 创建新的播放器并播放 mediaPlayer = MediaPlayer.create(context, songUri); mediaPlayer.start(); } catch (Exception e) { e.printStackTrace(); } } // 停止播放的方法 public void stopSong() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } }
然后在你的播放Activity里调用:
// 在播放页面初始化或者触发播放的地方调用 Uri songUri = getIntent().getParcelableExtra("SONG_URI"); // 假设你传递了歌曲的Uri MediaPlayerHelper.getInstance().playSong(this, songUri); // 记得在页面销毁时停止播放(可选,防止后台残留播放) @Override protected void onDestroy() { super.onDestroy(); MediaPlayerHelper.getInstance().stopSong(); }
解决方案2:用Service管理后台播放(推荐复杂场景)
如果你的App需要后台持续播放、锁屏控制等功能,用Service是更专业的做法,所有播放逻辑都统一在Service里,不受Activity生命周期影响。
先创建一个音乐播放Service:
package com.recycler.hp.navigationbar; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; import android.os.IBinder; public class MusicService extends Service { private MediaPlayer mediaPlayer; @Override public IBinder onBind(Intent intent) { return null; // 如果不需要绑定,返回null即可 } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { // 获取传递过来的歌曲Uri Uri songUri = intent.getParcelableExtra("SONG_URI"); if (songUri != null) { playSong(songUri); } } return START_STICKY; // 保证Service被杀死后能重启 } private void playSong(Uri songUri) { try { // 停止并释放旧的播放器 if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } mediaPlayer.release(); mediaPlayer = null; } // 创建新播放器并播放 mediaPlayer = MediaPlayer.create(this, songUri); mediaPlayer.start(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onDestroy() { super.onDestroy(); // 销毁时释放播放器资源 if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); } } }
然后在RecyclerView的点击事件里启动Service(同时可以打开播放页面):
// 点击歌曲时的逻辑 Uri songUri = ...; // 获取当前歌曲的Uri // 启动播放Service Intent serviceIntent = new Intent(context, MusicService.class); serviceIntent.putExtra("SONG_URI", songUri); context.startService(serviceIntent); // 打开播放Activity Intent playIntent = new Intent(context, PlayActivity.class); context.startActivity(playIntent);
解决方案3:通过广播通知旧页面停止播放
如果不想改动太多现有代码,可以用广播的方式,每次打开新的播放页面时,发送广播通知之前的播放页面停止播放。
首先在播放Activity里注册广播接收器:
package com.recycler.hp.navigationbar; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; public class PlayActivity extends Activity { private MediaPlayer mediaPlayer; private BroadcastReceiver stopPlayReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_play); // 注册广播接收器,接收停止播放的指令 stopPlayReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 停止当前播放并释放资源 if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } }; IntentFilter filter = new IntentFilter("com.recycler.hp.navigationbar.ACTION_STOP_PLAY"); registerReceiver(stopPlayReceiver, filter); // 初始化播放当前歌曲 Uri songUri = getIntent().getParcelableExtra("SONG_URI"); mediaPlayer = MediaPlayer.create(this, songUri); mediaPlayer.start(); } @Override protected void onDestroy() { super.onDestroy(); // 注销广播接收器 unregisterReceiver(stopPlayReceiver); if (mediaPlayer != null) { mediaPlayer.release(); } } }
然后在RecyclerView的点击事件里,先发送广播再打开新页面:
// 点击歌曲时 Intent stopIntent = new Intent("com.recycler.hp.navigationbar.ACTION_STOP_PLAY"); context.sendBroadcast(stopIntent); // 打开播放页面 Intent playIntent = new Intent(context, PlayActivity.class); playIntent.putExtra("SONG_URI", songUri); context.startActivity(playIntent);
内容的提问来源于stack exchange,提问作者Usama Hameed
相关产品推荐
相关产品推荐

