项目中需要用到把播放离线音乐设计成可以同时播放在线音乐和离线音乐的. onPrepareAsync 之前弄过,但是内部有很多错误, 所以一直使用onPrepare, 但是因为在网络差的环境中会阻塞线程, 痛定思痛花了心思研究了下,发现可以通过对播放错误进行处理, 结果完美解决.
下面是一些代码总结和心得:
点击音乐的时候需要song的集合传入, 这样虽然会播放歌曲但是会打开一个播放队列, 点击随机播放按钮的时候,这个队列会被打乱顺序, 取消随机播放的时候又会调成正常顺序. 会命令service在handler子线程中发送play_song , 让主线程处理. 在这里我考虑到方便项目维护方便, 所以在主线程处理的时候判断当前音乐是否在线音乐, 离线音乐的时候核心代码如下, 通过返回值判断歌曲是否能播放, 返回false时候弹toast 提示.
private boolean setDataSourceImpl(@NonNull final MediaPlayer player, @NonNull final String path) {
if (context == null) {
return false;
}
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
try {
// player.stop();
player.reset();
player.setOnPreparedListener(null);
if (path.startsWith("content://")) {
player.setDataSource(context, Uri.parse(path));
} else {
player.setDataSource(path);
}
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
MusicPlayerRemote.musicService.updateBeforeStart();
player.start();
UpdateStateUtil.updateNotifyCation();
}
});
} catch (Exception e) {
return false;
}
return true;
}
同时离线音乐返回true时候 完成准备播放下一首的逻辑
@Override
public void setNextDataSource(@Nullable final String path, Song song) {
if (context == null) {
return;
}
try {
mCurrentMediaPlayer.setNextMediaPlayer(null);
} catch (IllegalArgumentException e) {
return;
} catch (IllegalStateException e) {
return;
}
if (mNextMediaPlayer != null) {
mNextMediaPlayer.release();
mNextMediaPlayer = null;
}
if (path == null) {
return;
}
if (PreferenceUtil.getInstance(context).gaplessPlayback()) {
mNextMediaPlayer = new