异步任务AsyncTask控制音乐播放示例

音乐播放获取数据,配置权限,网络请求通知和刷新列表在这里不贴。只贴音乐播放服务和异步任务,有足够的注释。

一、音乐播放服务SongService

/**
 * 播放歌曲的service
 */
public class SongService extends Service {
    private MediaPlayer mediaPlayer;
    private int position;
    private boolean mediaIsReady;//播放器是否准备好

    public SongService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
//        throw new UnsupportedOperationException("Not yet implemented");
        return new SongBinder();
    }

    public class SongBinder extends Binder {
        public SongService getService() {
            return SongService.this;
        }
    }

    /**
     * 播放歌曲
     * @param songFilePath
     */
    public void playSong(String songFilePath){
        //判断是不是重新播放
        if (mediaPlayer==null) {
            mediaPlayer = new MediaPlayer();
            try {
                mediaPlayer.setDataSource(songFilePath);
                mediaPlayer.prepareAsync();
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mediaIsReady=true;
                        mp.start();
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
         //否则是暂停后继续
            mediaPlayer.seekTo(position);
            mediaPlayer.start();
        }
    }

    /**
     * 暂停播放
     */
    public void pauseSong(){
        if (mediaPlayer!=null&&mediaPlayer.isPlaying()){
            position=mediaPlayer.getCurrentPosition();//记录播放位置
            mediaPlayer.pause();
        }
    }

    /**
     * 停止播放
     */
    public void stopSong(){
        if(mediaPlayer!=null||mediaPlayer.isPlaying()){
            position=0;
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer=null;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if(mediaPlayer!=null){
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer=null;
        }
    }

    /**
     * 获取媒体总长度
     * @return
     */
    public int getDuration(){
        if (mediaPlayer!=null){
            return mediaPlayer.getDuration();
        }
        return 0;
    }

    /**
     * 获取当前播放位置
     * @return
     */
    public int getCurrentPosition(){
        if (mediaPlayer!=null){
            return mediaPlayer.getCurrentPosition();
        }
        return 0;
    }

    /**
     * 位置跳转
     * @param position
     */
    public void seekTo(int position){
        if (mediaPlayer!=null&&mediaPlayer.isPlaying()){
            mediaPlayer.seekTo(position);
        }
    }

    /**
     * 判断播放器是否准备好了
     * @return
     */
    public boolean mediaPlayerIsReady(){
        return  mediaIsReady;
    }
}

二、异步任务SongAsyncTask ,为方便维护,代码简洁清晰,没有写内部类,是一个独立的类

/**
 * 播放音乐的异步任务
 * Created by Devin Chen on 2016/12/18.
 */

public class SongAsyncTask extends AsyncTask<String,Integer,String> {
    private Context context;//上下文对象
    private SongService service;//音乐播放服务对象,服务里面有足够的播放控制方法和状态获取方法
    private SeekBar seekBar;//搜索条对象,也可以传入显示进度变化需要更新的其他对象

    /**
     * 构造方法,传递必要的参数
     * @param context
     * @param service
     * @param seekBar
     */
    public SongAsyncTask(Context context, SongService service, SeekBar seekBar) {
        this.context = context;
        this.service = service;
        this.seekBar = seekBar;
    }

    /**
     * 异步任务开始时调用
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //Log.i("SongAsyncTask","SongAsyncTask start...");
    }

    /**
     * 任务结束时调用
     * @param s
     */
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Log.i("SongAsyncTask","SongAsyncTask over!");
    }

    /**
     * publishProgress执行后调用,接收到进度值进行UI更新
     * @param values
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        seekBar.setMax(service.getDuration());//设置媒体总长度
        seekBar.setProgress(values[0]);//设置当前进度
        //Log.i("SongAsyncTask","总长度:"+service.getDuration());
        //Log.i("SongAsyncTask","当前位置:"+values[0]);
    }

    /**
     * 后台处理程序
     * @param params
     * @return
     */
    @Override
    protected String doInBackground(String... params) {
        //用死循环监视
       while (true){
           //如果检测到媒体已经准备好,就开始发送进度
            if(service.mediaPlayerIsReady()) {
                publishProgress(service.getCurrentPosition());
            }
       }
    }
}

三、最后说说怎么调用

音乐数据要在网络获取。我设计在service被绑定成功后向网络获取,也只有这时候,所需要的sevice才能获得,所以把异步任务的创建放在了ServiceConnection下的onServiceConnected方法内获取service和网络数据之后。

    /**
     * 服务连接对象
     */
    class SongServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder iBinder) {
            songService = ((SongService.SongBinder) iBinder).getService();//获得service对象
            SongHttpUtil.getSong(new SongGetDataMessage(), HTTP_METHOD_PLAY, songID);
            //在获取到songService后创建异步任务
            songAsyncTask = new SongAsyncTask(MusicPlayActivity.this, songService, seekPlay);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    }

网络数据在工具类中获取,获取成功后发来通知,我用EventBus通知。收到通知后播放音乐,启动异步任务。

    /**
     * OnEventBus接收方法:音乐列表请求返回
     *
     * @param message
     */
    @Subscribe
    public void onEvent(SongGetDataMessage message) {
        String action = message.getAction();
        switch (action) {
            case BaseMessage.REQUEST_ERROR:
                Toast.makeText(MusicPlayActivity.this, SERVICE_ERROR, Toast.LENGTH_SHORT).show();
                break;
            case BaseMessage.REQUEST_SUCCESS:
                SongJsonRootBean data = (SongJsonRootBean) message.getData();
                if (data != null) {
                    Glide.with(this).load(data.getSonginfo().getPicBig()).into(imgSongImage);//加载音乐图片
                    songFilePath = data.getBitrate().getFileLink();//获取歌曲路径
                    songService.playSong(songFilePath);//播放歌曲
                    songAsyncTask.execute();//开始异步任务
                } else {
                    Toast.makeText(MusicPlayActivity.this, SERVICE_GET_NO_DATA, Toast.LENGTH_SHORT).show();
                }
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值