当在线播放媒体文件时,第二次启动会导致IllegalStateException异常。

3

我正在创建一个简单的在线音频流应用程序。它有4个按钮:播放、停止、继续、暂停。当我按下停止按钮时,它能正常工作,但是当我再次启动后,应用程序崩溃了。它会出现以下异常:

java.lang.IllegalStateException
     at android.media.MediaPlayer._setAudioStreamType(Native Method)
     at android.media.MediaPlayer.setAudioStreamType(MediaPlayer.java:1723)
     at com.onlinestreaming.MediaPlayerActivity.onClick(MediaPlayerActivity.java:48)
     at android.view.View.performClick(View.java:5204)
     at android.view.View$PerformClick.run(View.java:21153)
     at android.os.Handler.handleCallback(Handler.java:739)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:148)
     at android.app.ActivityThread.main(ActivityThread.java:5417)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

这是我所做的:

 @Override
    public void onClick(View v) {

        int id = v.getId();
        switch (id) {
            case R.id.play:

                    pd = new ProgressDialog(this);
                    pd.setMessage("Buffering");
                    pd.show();
                    mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    mp.setOnPreparedListener(this);
                    mp.setOnErrorListener(this);
                    try {
                        // mp.setDataSource("http://www.robtowns.com/music/blind_willie.mp3");
                        //mp.setDataSource("http://picosong.com/zkWc");
                        mp.setDataSource("http://songs1.djmazadownload.com/music/indian_movies/Banjo%20%282016%29/01%20-%20Bappa%20-%20Banjo%20%5BDJMaza.Cool%5D.mp3");
                    } catch (IOException e) {
                        Toast.makeText(this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                    mp.prepareAsync();
                    mp.setOnCompletionListener(this);
                break;

            case R.id.Stop:
                mp.stop();
                mp.reset();
                mp.release();

                break;

            case R.id.Resume:
                mp.start();
                break;

            case R.id.Pause:
                Toast.makeText(this, "Hit", Toast.LENGTH_SHORT).show();
                if (mp.isPlaying()) {
                    mp.pause();
                } else {
                    mp.start();
                }
                // mp.pause();
                break;
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        pd.dismiss();
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        pd.dismiss();
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {

        Toast.makeText(this, "Prepared Finished", Toast.LENGTH_SHORT).show();
        pd.setMessage("Playing.......");

        mp.start();
    }
2个回答

1

当用户点击“停止”时,您需要调用mp.release()。这将使MediaPlayer处于“End”状态(请参见状态图)。

因此,如果下一次用户点击“开始”,您必须使用一个新的MediaPlayer实例,因为setAudioStreamType()只能在以下状态中使用(请参见MediaPlayer文档):

空闲、已初始化、已停止、已准备、已启动、已暂停、已播放完成


1
在停止按钮按下时,您正在释放MediaPlayer对象的资源。
release():
释放与此MediaPlayer对象关联的资源。调用此方法被认为是一种良好实践,当您完成使用MediaPlayer时应该调用此方法。特别是,每当应用程序的Activity暂停(调用其onPause()方法)或停止(调用其onStop()方法)时,除非应用程序有特殊需要保留对象,否则应调用此方法来释放MediaPlayer对象。除了持有不必要的资源(例如内存和编解码器实例)之外,如果不再需要MediaPlayer对象,则未立即调用此方法还可能导致移动设备持续耗电,并且如果设备上不支持多个相同编解码器实例,则可能会导致其他应用程序的播放失败。即使支持多个相同编解码器实例,当同时使用不必要的多个实例时也可能会出现某些性能降级。
因此,请从停止按钮clicklistener中删除mp.release()。
 case R.id.Stop:
        mp.stop();
        mp.reset();
      break;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接