3

サウンドを再生するボタンを備えたAndroidアプリがあります。サウンドを再生するためのコード:

if (mp != null)
{
    mp.release();
}
mp = MediaPlayer.create(this, R.raw.match);
mp.start();

mp はアクティビティのフィールドです。

public class Game extends Activity implements OnClickListener {
/** Called when the activity is first created. */
//variables:
MediaPlayer mp;
//...

アプリは正常に動作しますが、エミュレーターでボタンを約 200 回クリックした後、アプリがクラッシュし、このエラーhttps://dl.dropbox.com/u/5488790/error.txtが表示されました (投稿方法がわかりませんでした)ここではまともに表示されます)
MediaPlayer オブジェクトがメモリを消費しすぎているためだと思いますが、mp.release() はこれを処理するはずではありませんか? ここで何が間違っていますか?

4

4 に答える 4

3

ボタンに効果音を付ける場合MediaPlayer、一般的にこの操作には重すぎます。サウンド データをメモリにロードするだけで、毎回不必要なレイテンシが発生します。SoundPool代わりに using を検討する必要があります。

MediaPlayerいずれの場合も、毎回を解放して再作成する正当な理由はありません。を使用する場合MediaPlayerは、ボタンのクリックで単一のインスタンスを制御します。

MediaPlayer mp;

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

    //Other init code

    //Create the player this way so it doesn't auto-prepare
    mp = new MediaPlayer();
    AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.match);
    mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
    afd.close();
}

public void onDestroy() {
    super.onDestroy();
    //Release it only when no longer needed
    mp.release();
    mp = null;
}

public void onButtonClick(View v) {
    if (mp.isPlaying()) {
        mp.stop();
    }
    //Play the sound
    mp.prepare();
    mp.start();
}

お役に立てば幸いですが、SoundPoolこのサウンドが単なる短いエフェクトである場合は、代わりに使用することを強くお勧めします。

于 2012-09-06T15:46:34.557 に答える
2

あなたのコードは動作するはずですが、明らかにrelease()すべてをリリースしているわけではありません。

R.raw.matchサウンドを再生するたびにリロードする必要があるためかもしれません。R.raw.matchが単なる短い効果音である場合は、SoundPool代わりに使用することを検討してください。

使用する場合は、メモリの問題を防ぐために一度SoundPoolだけロードする必要があります。R.raw.match

このチュートリアルには、使用方法の良い例があります: http://www.vogella.com/articles/AndroidMedia/article.html#tutorial_soundpool

ほとんどの場合、SoundPool の 1 つのインスタンスを作成し、サウンドを 1 回ロードして、必要なときに再生するだけです。

お役に立てれば!

編集

MediaPlayer を使用する場合は...

public class Blah extends Activity implements OnClickListener {
   MediaPlayer mp;

   @Override 
   public void onCreate(Bundle b)
   {
      // blah blah
      mp = MediaPlayer.create(R.raw.match);

      // blah blah
   }

   @Override
   public void onClick(View v)
   {
      if (v.getId() == yourButtonID)
      {
         // play sound from beginning
         mp.seekTo(0);
         mp.start();
      }
   }
}

この方法では、インスタンスを 1 つだけ作成し、それを再生したいときはいつでも最初まで巻き戻して再生します。

于 2012-09-06T15:46:37.923 に答える
0

試す

if (mp != null)
        {
            mp.release();
        }
        mp = MediaPlayer.create(this, R.raw.match);
        mp.prepare(); // not needed 
        mp.start();

幸運を!!

于 2012-09-06T15:35:48.113 に答える