MediaPlayer是一个棘手的混蛋。我建议您看一下示例应用程序,其中的MediaPlayer不良设计可以通过查看为确保一致的媒体播放体验而必须编写的乱七八糟的代码而变得明显。
如果有什么需要,在查看示例之后,您会发现当他们想要跳过曲目时,他们实际上会 重置 并释放……
mPlayer.reset(); mPlayer.release();
…以及以后准备加载新曲目时…
try { mPlayer.reset(); mPlayer.setDataSource(someUrl); mPlayer.setonPreparedListener(new MediaPlayer.onPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { //bam! } }); mPlayer.prepareAsync(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); }我添加了try /
catch,因为在某些设备/操作系统版本上,MediaPlayer比其他版本差,有时它只是做一些奇怪的事情。您应该具有能够对这些情况做出反应的接口/侦听器
更新 :
这是我停止(或暂停)音乐播放时使用的一种方法(主要是从示例应用程序中获取,该程序正在服务中运行,并且已对其进行了修改以适合我自己的应用程序,但仍然可以)。
stop和都使用第一种方法
pause,前者通过
true,后者
false
void relaxResources(boolean releaseMediaPlayer) { stopForeground(true); stopMonitoringPlaybackProgress(); // stop and release the Media Player, if it's available if (releaseMediaPlayer && mPlayer != null) { mPlayer.reset(); mPlayer.release(); mPlayer = null; } // we can also release the Wifi lock, if we're holding it if (mWifiLock.isHeld()) { mWifiLock.release(); }}这是以下内容的一部分
processPauseRequest():
if (mState == State.Playing) { // Pause media player and cancel the 'foreground service' state. mState = State.Paused; mPlayer.pause(); dispatchBroadcastEvent(ServiceConstants.EVENT_AUDIO_PAUSE);//notify broadcast receivers relaxResources(false); // while paused, we always retain the mp and notification这是
processStopRequest()(简化)的一部分:
void processStopRequest(boolean force, final boolean stopSelf) { if (mState == State.Playing || mState == State.Paused || force) { mState = State.Stopped; // let go of all resources... relaxResources(true); currentTrackNotification = null; giveUpAudioFocus(); }}现在,核心部分是下一个/跳过…
这就是我的工作
void processNextRequest(final boolean isSkipping) { processStopRequest(true, false); // THIS IS importANT, WE RELEASE THE MP HERE mState = State.Retrieving; dispatchBroadcastEvent(ServiceConstants.EVENT_TRACK_INFO_LOAD_START); // snipped but here you retrieve your next track and when it's ready… // you just processPlayRequest() and "start from scratch"这就是MediaPlayer示例的操作方式(位于samples文件夹中),我没有遇到任何问题。
话虽这么说,但我知道您的意思,当您说整个过程都受阻时,我已经看到了,这是MP的错误。如果您收到ANR,我想查看它的日志。
作为记录,这是我“开始演奏”的方式(已省略了许多自定义代码,但您可以看到MP的东西):”
void beginPlaying(Track track) { mState = State.Stopped; relaxResources(false); // release everything except MediaPlayer try { if (track != null) { createMediaPlayerIfNeeded(); mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mPlayer.setDataSource(track.audioUrl); } else { processStopRequest(true, false); // stop everything! return; } mState = State.Preparing; setUpAsForeground(); //service // starts preparing the media player in the background. When it's done, it will call // our onPreparedListener (that is, the onPrepared() method on this class, since we set // the listener to 'this'). // Until the media player is prepared, we *cannot* call start() on it! mPlayer.prepareAsync(); // We are streaming from the internet, we want to hold a Wifi lock, which prevents // the Wifi radio from going to sleep while the song is playing. if (!mWifiLock.isHeld()) { mWifiLock.acquire(); } } catch (IOException ex) { Log.e("MusicService", "IOException playing next song: " + ex.getMessage()); ex.printStackTrace(); }}最后一点,我注意到当音频流或源不可用或不可靠时,就会发生“阻止所有内容的媒体播放器”。
祝好运!让我知道您是否想查看任何特定内容。



