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语句,因为在某些设备/ OS版本中,MediaPlayer的是比别人差,有时它只是做怪异的东西。你应该有一个接口/监听器,它能够反应这些情况
UPDATE的:
这是当我停止我使用的方法(或暂停),我的音乐播放(主要来自示例应用程序采取,这是运行在一个服务,它已被修改,以适应我自己的应用程序,但仍然)。
第一种方法是通过两个stop
和pause
使用的,前者通过true
,后者false
/**
* Releases resources used by the service for playback. This includes the "foreground service"
* status and notification, the wake locks and possibly the MediaPlayer.
*
* @param releaseMediaPlayer Indicates whether the Media Player should also be released or not
*/
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的样本是如何做的(在样本文件夹中找到),我有没有它有问题。
这就是说,我知道你说的是什么意思,你把整个事情都封锁了,我已经看到了,这是MP麻烦。如果你得到一个ANR,我想看看它的日志。
为了记录在案这里就是我“开始播放”(大量的自定义代码已经被遗漏的,但你能看到MP的东西):”
/**
* Starts playing the next song.
*/
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
/* STRIPPED ALL CODE FROM REMOTECONTROLCLIENT, AS IT ADDS A LOT OF NOISE :) */
// 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();
}
}
最后一点,我注意到当音频流或源不可用或不可靠的“媒体播放器阻止一切”的发生。
祝你好运!让我知道如果有什么具体的你想看到的。
做,如果你插入一个电话'你得到什么行为在“重置”调用之前立即释放?它应该取消准备(我以为'重置'会做同样的...)。 – Dave
嗨,请原谅我迟到的答案。我不能在'release'后面调用'reset',也不能在'release'后调用任何'IllegalStateException'。但即使我尝试再次初始化MediaPlayer时,UI在调用'release'方法时也会冻结:(但值得一试 – Flixer
啊,当然,你在'释放'之后不会调用任何东西。对不起,wasn不要想......我从来没有遇到任何一种阻塞方法的问题,但是,你能否确定它是版本还是设备特定的?另外,作为一般规则,在开始使用AsyncTask – Dave