首页 > 解决方案 > MediaPlayer 突然停止播放

问题描述

你好 StackOverFlow 社区,我最近有这个问题,我创建了一个 Whack A Mole 游戏,然后有时声音停止播放,它只显示这个错误,我在互联网上搜索,它说使用OnPreparedMediaPlayer,我不知道它是如何工作的

E/MediaPlayerNative:在状态 0 中停止调用,mPlayer(0x7897fe1440)\

或者

E/MediaPlayerNative: 错误 (-38, 0)

这是我的游戏活动

public class Game extends AppCompatActivity {

public MediaPlayer mPlayerShot;
public MediaPlayer mPlayerMiss;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getSupportActionBar().hide();

    setContentView(R.layout.activity_game);

    mTimeView = (TextView) findViewById(R.id.textTimeVal);
    mScoreView = (TextView) findViewById(R.id.textScoreVal);

    // Get saved difficulty, default to Medium if no pref exists
    final SharedPreferences sharedPref = this.getPreferences(Context.MODE_PRIVATE);
    currentDiff = sharedPref.getString("saved_difficulty", "Medium");

    // Start the game!
    mTimer.start();
    handler.post(moleLoop);

    varClose = false;

    mPlayerShot = MediaPlayer.create(getApplicationContext(), R.raw.playerlaser);
    mPlayerMiss = MediaPlayer.create(getApplicationContext(), R.raw.enemylaser);

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

    // Scale mole translation based on device dimensions
    int sHeight = metrics.heightPixels;
    yValue = (sHeight/8)*-1;

}

    @Override
    public void onPause(){
    super.onPause();

    varClose = true;
    mTimer.cancel();

    mPlayerShot.stop();
    mPlayerMiss.stop();

}

@Override
public void onStop() {
    super.onStop();

    varClose = true;
    mTimer.cancel();

    mPlayerShot.stop();
    mPlayerMiss.stop();

}

public Runnable moleLoop = new Runnable() {

    int varPrevRandMole = 10;

    @Override
    public void run () {

        // Pick a mole at random, if you get the same twice, re-roll until it's different
        varRandMole = new Random().nextInt(8);

        if (varRandMole == varPrevRandMole){
            do
                varRandMole = new Random().nextInt(8);
            while (varRandMole == varPrevRandMole);
        }

        varPrevRandMole = varRandMole;

        // Pop the mole up
        molesClick[varRandMole].animate().translationY(yValue).setDuration(moleUpTime);

        // Timer to pop our mole back down if player fails to hit it
        new Timer().schedule(new TimerTask() {
            public void run() {

                if (!varClose) {

                    for (int i = 0; i < 9; i++) {
                        if (molesClick[i].getTranslationY() == yValue) {

                            final int j = i;

                            // Sets the mole back to its beginning position
                            // run this update on the UI thread as we need a "looper" thread
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    molesClick[j].animate().translationY(0).setDuration(5);
                                }
                            });

                            if (mPlayerMiss.isPlaying() && mPlayerMiss != null) {
                                mPlayerMiss.stop();
                                mPlayerMiss.reset();
                                mPlayerMiss.release();
                            }
                            mPlayerMiss.start();

                            // Deduct a life if we miss a mole
                            varLives -= 1;
                            updateLives(varLives);

                        }
                    }
                }
            }
        }, timeInterval);

        if (!varClose) {
            handler.postDelayed(moleLoop, timeInterval);
        }
    }
};

public void directHit(){

    if (mPlayerShot != null && mPlayerShot.isPlaying()){
        mPlayerShot.stop();
        mPlayerShot.reset();
        mPlayerShot.release();
    }

    mPlayerShot = MediaPlayer.create(getApplicationContext(), R.raw.playerlaser);
    mPlayerShot.start();

    // Award points, update score
    varScore += 250;
    updateScore(varScore);
}

}

标签: androidandroid-studioandroid-mediaplayer

解决方案


以下是我注意到的几个问题。

您必须在发布后重新创建媒体播放器

   // first check null
if (mPlayerMiss != null && mPlayerMiss.isPlaying()) {
          mPlayerMiss.stop()
          mPlayerMiss.reset();
          mPlayerMiss.release();
        }
      //creating media player again here
      mPlayerMiss= MediaPlayer.create(getApplicationContext(), R.raw.playermissfilename);
      mPlayerMiss.start();

在 onPause 方法中,您正在调用mediaPlayer.stop();method 。检查 null 和更好的调用,mediaPlayer.release()而不是 stop 。

你在mediaPlayer.stop()里面打电话onPause()所以不需要再打电话onStop()

如果您仍然面临问题(不是最好的方法),请在停止和重置播放器时使用 try/catch

if (mPlayerMiss.isPlaying() && mPlayerMiss != null) {
  try {
       mPlayerMiss.stop();
       mPlayerMiss.reset();
       mPlayerMiss.release();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

推荐阅读