对于用Context.startService()启动的service生命周期为onCreate()-onStartCommand()-onDestroy();如果多次用context.startService启动service只会多次执行onStartCommand()方法。根据音乐播放器的特性使用Context.startService()调用在合适不过了。

public class MyMusicPlayer extends Service implements

MediaPlayer.OnCompletionListener {
public static final String TAG = "MyMusicPlayer";
public static final String ACTION_ADD_TO_QUEUE = "com.example.musicmedia.ADD_TO_QUEUE";//指定action
private ConcurrentLinkedQueue<Uri> mTrackQueue;//它是一个基于链接节点的无界线程安全队列。该队列的元素遵循先进先出的原则。头是最先加入的,尾是最近加入的。插入元素是追加到尾上。提取一个元素是从头提取。
private MediaPlayer mMediaPlayer;

public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");  
mTrackQueue = new ConcurrentLinkedQueue<Uri>();//初始化并发队列
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
if (ACTION_ADD_TO_QUEUE.equals(action)) {
Uri trackUri = intent.getData();//获取音乐的资源
Log.i("MyMusicPlayer", trackUri.toString());
this.addTrackToQueue(trackUri);//添加资源
}
return START_NOT_STICKY;//返回值确定了该Service不会在系统关闭它后重新启动,执行一次性操作经常用这个。
}

@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
if (mMediaPlayer != null) {//当service销毁的时候释放mMediaPlayer资源
mMediaPlayer.release();
mMediaPlayer = null;
}
}

//如果已经开始播放就往队尾添加新音乐资源,否则创建MediaPlayer并开始播放
private void addTrackToQueue(Uri trackUri) {
if (mMediaPlayer == null) {
try {
Log.i("MyMusicPlayer", "addTrackQueue:" + trackUri);
mMediaPlayer = MediaPlayer.create(this, trackUri);//初始化mMediaPlayer,因为用MediaPlayer.create初始化所以不用调用prepare()方法准备。该初始化自动完成
mMediaPlayer.setOnCompletionListener(this);//注册一个回调函数,音频播放完成后调用
mMediaPlayer.start();//开始播放
} catch (Exception e) {
stopSelf();//停止service
}
} else {
mTrackQueue.offer(trackUri);//向队列添加元素
}
}

//曲目播放完毕,开始播放下一首或者停止Service
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.reset();//重用MediaPlayer对象
Uri nextTrackUri = mTrackQueue.poll();//从队列里面取出元素
if (nextTrackUri != null) {
try {
mMediaPlayer.setDataSource(this, nextTrackUri);//初始化mMediaPlayer
mMediaPlayer.prepare();//准备
mMediaPlayer.start();//播放
} catch (IOException e) {
stopSelf();
}
} else {
stopSelf();//停止service
}
}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相对完美的后台Service实现播放音乐功能的更多相关文章

  1. 在博客中实现播放音乐功能(QQ,网易,酷狗,虾米,百度)

    1.在页头head标签里添加: <link rel="stylesheet" href="https://static.likepoems.com/cdn/apla ...

  2. MUI---IOS切换到后台继续播放音乐

    应用切换到后台继续音乐播放HBuilder默认生成的应用在iOS是不支持后台音乐播放的,当应用切换到后台时音乐将暂停播放,下次切换到前台继续播放.如果要支持应用切换到后台后继续播放音乐功能需要进行额外 ...

  3. iOS多媒体总结&进入后台播放音乐

    1. 播放mp3需要导入框架,AVFoundation支持音频文件(.caf..aif..wav..wmv和.mp3)的播放. #import <AVFoundation/AVFoundatio ...

  4. Android(java)学习笔记234: 服务(service)之音乐播放器

    1.我们播放音乐,希望在后台长期运行,不希望因为内存不足等等原因,从而导致被gc回收,音乐播放终止,所以我们这里使用服务Service创建一个音乐播放器. 2.创建一个音乐播放器项目(使用服务) (1 ...

  5. IOS 后台执行 播放音乐

    iOS 4開始引入的multitask.我们能够实现像ipod程序那样在后台播放音频了. 假设音频操作是用苹果官方的AVFoundation.framework实现.像用AvAudioPlayer.A ...

  6. IOS后台运行 之 后台播放音乐

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

  7. Android(java)学习笔记177: 服务(service)之音乐播放器

    1.我们播放音乐,希望在后台长期运行,不希望因为内存不足等等原因,从而导致被gc回收,音乐播放终止,所以我们这里使用服务Service创建一个音乐播放器. 2.创建一个音乐播放器项目(使用服务) (1 ...

  8. iOS设备后台播放音乐方法

    iOS设备后台播放音乐方法 1 在设置Capabliites中打开Background Modes,选择Audio And AirPlay 2 在控制viewDidLoad中添加下面代码 AVAudi ...

  9. 使用Service组件实现简单的音乐播放器功能 --Android基础

    1.本例利用Service实现简单的音乐播放功能,下面是效果图.(点击开始播放开启服务,音乐播放,点击“停止播放”关闭服务,音乐停止播放.) 2.核心代码: MusicService.java: pa ...

随机推荐

  1. Lua学习笔记(四):表和数组

    表 在Lua中,表(table)是十分重要的一种数据结构,实际上Lua对于复杂数据类型也仅提供了表给我们,我们通过表可以实现我们需要的大部分重要的数据结构,比如数组. table类型实现了关联数组,关 ...

  2. list删除操作 java.util.ConcurrentModificationException

    首先大家先看一段代码: public static void main(String[] args) { List<String> listStr = new ArrayList<S ...

  3. 音频视频播放(jquery中将jquery方法转化成js方法)

    在jQuery中没有音频视频直接播放的方法,我们在写音频视频时,应该将jquery的方法转化为js方法:play():pause() 补充:   将jq对象转化成js对象写法: var music=$ ...

  4. delphi 设置超链接

     的属性 的事件 的方法 //1设置链接类型//2获取样式 链接和提示信息 //title是提示信息//HTTPS https://<a href="https://www.baidu ...

  5. some websit

    Baidu:VideoView onVideoSizeChanged http://code.taobao.org/p/TangHuZhao/src/ http://code.taobao.org/p ...

  6. 如何将松散的dll打包进需要发布的exe

    我们需要发布的exe文件很多时候都可能会依赖于一堆松散的dll,如果想在发布的时候只提供exe文件,而不想把一大堆dll一起放在和exe同一个文件夹下,是有方法的,该方法由CLR via C#作者提出 ...

  7. [原]生产环境下的nginx.conf配置文件(多虚拟主机)

    [原]生产环境下的nginx.conf配置文件(多虚拟主机) 2013-12-27阅读110 评论0 我的生产环境下的nginx.conf配置文件,做了虚拟主机设置的,大家可以根据需求更改,下载即可在 ...

  8. MYSQL之HANDLER_READ_*详细讲解

    http://www.databaseclub.com/category/performance/

  9. Percona-Galera-Monitoring-Template监控模板说明

    http://blog.chinaunix.net/uid-16844903-id-4054635.html 官网链接:http://www.percona.com/doc/percona-monit ...

  10. Python基础教程之List对象 转

    Python基础教程之List对象 时间:2014-01-19    来源:服务器之家    投稿:root   1.PyListObject对象typedef struct {    PyObjec ...