音乐播放器---解决使用MediaPlayer开发时抛IllegalStateException异常的办法

        在使用MediaPlayer开发音乐播放器时,最常遇见的应该是IllegalStateException异常了。首先要明确IllegalStateException这个异常是指“非法的状态”。Android的mediaplayer API中用到了JNI,也就是我们的java代码是要调用native的C++方法的(mediaplayer是用c++实现的),而这里之所以出现这个异常,就是因为我们java里面的mediaplayer对象的状态和native的对象状态发生了不一致。

        如下是MediaPlayService.java中实现播放的代码,报异常是在mediaPlayer.setDataSource(path)这一行。

        public void play(String path){
        //Log.d(TAG,"play file path : " + path);
        if(mediaPlayer.isPlaying()){
            mediaPlayer.stop();
        }

        try {
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            //reset()后,mediaplayer 处于IDLE状态
            mediaPlayer.reset();
            mediaPlayer.setDataSource(path);
            mediaPlayer.prepareAsync();

        } catch (Exception e) {
            //Log.d(TAG, "play   IllegalStateException----");
            e.printStackTrace();
        }
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                // 装载完毕回调
                mediaPlayer.start();
                //用于更新歌曲名称,歌唱者信息
                Intent intent = new Intent();
                intent.setAction(START_ACTION);
                sendBroadcast(intent);
                new Thread(){
                    @Override
                    public void run() {
                        while (mediaPlayer.isPlaying()){
                            // 将SeekBar位置设置到当前播放位置
                            Message msg = Message.obtain();
                            Bundle data = new Bundle();
                            msg.what = 0;
                            //获取歌曲的时长,单位是毫秒
                            int length = mediaPlayer.getDuration();
                            //获取歌曲当前的播放进度
                            int currentLength = mediaPlayer.getCurrentPosition();
                            data.putInt("length", length);
                            data.putInt("currentLength", currentLength);
                            msg.setData(data);
                            try {
                                // 每1秒更新一次位置
                                MusicItemActivity.handler.sendMessage(msg);
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
            }
        });
    }

在分析解决该异常之前,需要对mediaplayer的各状态有所了解,如下图所示。详细的介绍可以参考http://blog.****.net/hejjunlin/article/details/52349221 

在mediaPlayer = new MediaPlayer()后,mediaPlayer处于Idle状态,通过setDataSource,之后可以正常播放音乐。此时如果点击暂停按钮,在点击下一首播放(该条件是我自己测试的时候出现的)就会报出IllegalStateException异常。参考该图可以发现原因,播放时处于Started状态,通过调用setDataSource加载播放路径时mediaPlayer状态不对,需要通过调用reset()使mediaPlayer重新处于Idle状态即可,如代码中注释的那样。

音乐播放器---解决使用MediaPlayer开发时抛IllegalStateException异常的办法