zoukankan      html  css  js  c++  java
  • 相对完美的后台Service实现播放音乐功能

    对于用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
    }
    }
    }

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

  • 相关阅读:
    silverlight的TranslateTransform 的使用
    720 JavaScript函数的this指向
    JavaScript数组
    JavaScriptDOM事件
    JavaScript流程控制语句
    CSS布局案例
    JavaScriptDOM基础
    JavaScriptDOM事件
    JavaScript基础语法
    JavaScript的String对象相关方法
  • 原文地址:https://www.cnblogs.com/liyuanjinglyj/p/4656581.html
Copyright © 2011-2022 走看看