播放歌曲这种后台操作放到了Service中。由于用户会播放不同歌曲,每次播放不同歌曲会传递不同的歌曲地址,如果用StartService需要每次都在Intent上绑定不同的值 而且会不断的去StartService,所以采用了BindService来绑定服务。只需要一次绑定后获得自定义Service中定义的bind对象就能方便的操作Service中的定义的方法从而操作歌曲。
歌曲服务类代码如下:
public class MusicService extends Service {
private MediaPlayer player;//声明一个MediaPlayer对象
private String preUri;
private ControlMusicBinder musicBinder = new ControlMusicBinder();
public class ControlMusicBinder extends Binder{
public void playMusic(final String uri)
{
new Thread(new Runnable() {
@Override
public void run() {
if(preUri != null && preUri.equals(uri)){
if(player != null && player.isPlaying()){
player.pause();
}
else {
player.start();
}
}
else {
try{
pauseMusic();
player.reset();
player.setDataSource(MusicService.this,Uri.parse(uri));
player.prepare();
player.start();
preUri = uri;
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}).start();
}
public void pauseMusic()
{
new Thread(new Runnable() {
@Override
public void run() {
if(player!=null && player.isPlaying()){
player.pause();
}
}
}).start();
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO 自动生成的方法存根
return musicBinder;
}
//创建服务
@Override
public void onCreate() {
player = new MediaPlayer();
super.onCreate();
}
//销毁服务
@Override
public void onDestroy() {
//当对象不为空时
if (player != null) {
player.stop();//停止播放
player.release();//释放资源
player = null;//把player对象设置为null
}
super.onDestroy();
}
}
操作歌曲用到了MediaPlayer对象。在播放歌曲方法中首先判断用户点击是不是之前的歌曲,如果是同一首歌则判断播放状态如果在播放中就暂停播放如果在暂停状态就播放歌曲,如果不是同一首歌先设置空闲状态,再调用setDataSource方法设置歌曲资源,然后调用prepare装载音频。用这样的方式来播放下一首歌可以减少内存消耗(如果用静态方法create,每次会返回新创建的MediaPlayer对象。)
在主线程中绑定好歌曲服务后就可以自由操作歌曲了。主线程中绑定歌曲服务的代码如下:
Intent musicServiceIntent = new Intent(this,MusicService.class);
bindService(musicServiceIntent,musicServiceConnection,BIND_AUTO_CREATE);
private ServiceConnection musicServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
musicBinder = (MusicService.ControlMusicBinder)service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};