2017-10-23 14 views
0

文字列を反復するループを作成していて、存在する文字によって異なるサウンドを再生しています。残念ながら、サウンドが終了するのを待ってから続行すると、メディアプレイヤーにエラーが発生します。続行する前にサウンドが終了するのを待つ

for (char ch : morsechars) { 
      if (Character.toString(ch).equals(".")) { 
       Log.d("play: ", "dot"); 
       try { 
        startPlayback(); 
       } catch (Exception e){ 
        e.printStackTrace(); 
       } 
      } else if (Character.toString(ch).equals("-")){ 
       Log.d("play: ", "dash"); 
       try { 
        startPlayback(); 
       } catch (Exception e){ 
        e.printStackTrace(); 
       } 
      } 
     } 

と私のプレーヤーは、次のようになります:私のループはこのようになりますループの次の文字に移動する前に完了リスナーを待つか

public void startPlayback() throws Exception{ 
     play = MediaPlayer.create(this, dotFILE); 
     play.start(); 
     isplaying = true; 
     while (isplaying == true){ 

     } 


     play.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
      public void onCompletion(MediaPlayer play) { 
       isplaying = false; 
       play.stop(); 
       play.reset(); 
       play.release(); 
      } 
     }); 
    } 

イムわかりません。

答えて

1

1)MediaPlayerはこの仕事には適していません。 SoundPoolを見てください。繰り返し再生される短い音を対象としています。

2)あなたの場合は、実際にはループではありません。サウンドは非同期で再生されるため、再生するコールが互いに重ね合わされた状態になります。これにより、MediaPlayerのネイティブコードが利用可能なリソースを使い果たすことになります。

あなたが望むのは、一連のコールバックです。 MediaPlayerにはすでに使用している完了コールバックがありますが、必要なものと正確には見えますが、ユースケースでは十分ではありません。 MediaPlayerのネイティブコードは、後続の呼び出しが再生されるのに十分速くリソースを解放することができず、同じリソースが使い果たされます。それはMediaPlayerがどのように機能するかについての不幸な現実です。

SoundPoolには便利な補完コールバックがありませんが、この場合はおそらく2つのサウンドサンプルしかなく、どれくらいの長さであるかがわかります。おそらく、単純なタイマーの遅延で十分です。この効果を得るにはHandler.postDelayedを使用できます。各コールバックイベントでは、次のサウンドを再生し、現在のサウンドを追跡するために使用している変数を前に進め、同じコールバックを再度ポストして残りのサウンドを再生します。それは非同期ループの一種です。ここでは、何が起こっているか理解するために

UPDATE

HandlerにAndroidのドキュメントからのビットは次のとおりです。

Aハンドラを使用すると、スレッドのメッセージキューに関連付けられたメッセージとのRunnableオブジェクトを送信して処理することができます。各Handlerインスタンスは、単一のスレッドとそのスレッドのメッセージキューに関連付けられています。新しいHandlerを作成すると、それを作成しているスレッドのスレッド/メッセージキューにバインドされます。その時点から、そのメッセージキューにメッセージと実行可能ファイルを配信し、メッセージから出てくるように実行しますキュー。あなたのコードの構造についての私の推測では、修正するために近ければ

だから、あなたはあなたのActivityクラスのメンバとしてHandlerオブジェクトを作成します。これはそれをGUIスレッドにバインドします。あなたはそこで多くの作業をしないのでOKです。投稿されるタスクとして機能するには、Runnableも必要です。それをあなたのクラスのメンバーにもしてください。そしてあなたの文字がメンバーになるようにあなたのStringが必要になります。また、あなたが現在いるキャラクターを追跡するにはintが必要です。

private Handler playMorseHandler = new Handler(); 
private String morseChars = ".--...---"; // I don't know where you set this 
private int charIndex = 0; 
private Runnable playMorseTask = new Runnable() { 
    if (morseChars == null || 
     charIndex < 0 || 
     charIndex >= morseChars.length()) { 
     Log.w("whateverTag", "Basic assumptions failed"); 
     return; 
    } 
    char ch = morseChars.charAt(charIndex); 
    long lengthOfClip = 0L; 
    boolean postAgain = true; 
    if (ch == '.') { 
     Log.d("play: ", "dot"); 
     lengthOfClip = 300L; // I don't know how long your clips are 
     try { 
      startPlayback(); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } else if (ch == '-') { 
     Log.d("play: ", "dash"); 
     lengthOfClip = 500L; // I don't know how long your clips are 
     try { 
      startPlayback(); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } else { 
     Log.d("whateverTag", "unexpected input"); 
     postAgain = false; 
    } 
    ++charIndex; 
    if (postAgain && charIndex < morseChars.length()) { 
     playMorseHandler.postDelayed(this, lengthOfClip); 
    } 
}; 

あなたがサウンドの再生を開始したい場合はいつでも、あなたは、単に呼び出す:

charIndex = 0; 
playMorseHandler.post(playMorseTask); 

残された唯一の事はあなたのstartPlayback()メソッドを作ることであろうSoundPoolの代わりを使用することで正しいことを、行いますMediaPlayer。これは、前述したように、MediaPlayerは必然的にシステムがこれらの短い音をすばやく再生するリソースを使い果たしてしまうからです。

+0

Iveは見て回りましたが、単純なHandler.postDelayedを実装する方法を見つけることができないようですが、コードサンプルを提供できますか? –

+0

コードを実行しようとする前に動作し遅延しているようですが、ループは待機しません。それをやり直す方法がわからないので、私は継続する前にある程度の時間を待つことができます。 @Dave –

+0

あなたはforループをまったく使用しないことを意図していました。それは使用する正しい構成体ではありません。代わりに、自分自身をループ機構として呼び出すコールバックを使用する必要があります。私はちょっと私の答えを更新して、私が何を意味するのかを示しますが、ちょうどうまくいくものを提供するあなたのプロジェクトについては十分に分かりません。あなたはそれをテストし、あなた自身でいくつかのことを試してみる必要があります。 – Dave

関連する問題