2017-02-16 22 views
0

新しいスレッドを開始してオーディオを再生します。 runメソッドの初めに、最初にaudiotrackを作成します。audiotrackがオーディオを再生し終えたら、私はaudioTrack.setPlaybackPositionUpdateListenerに何かをするように設定しました。最後に、実際にオーディオを再生するにはaudiotrack.write()に電話します。スレッド内にイベントリスナーを設定する

コードスニペットはダウン以下の通りです:

@Override 
public void run() { 
audioTrack = new AudioTrack(listenerService.m_amAudioManager.STREAM_VOICE_CALL, listenerService.sampleRate, AudioFormat.CHANNEL_OUT_MONO, listenerService.audioFormat, listenerService.minBufSize/8, AudioTrack.MODE_STREAM); 
audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener() { 
    @Override 
    public void onMarkerReached(AudioTrack track) { 
     endReached(); 
    } 
}); 
audioTrack.play(); 
audioTrack.setNotificationMarkerPosition(959); 
audioTrack.write(rReadShortBuffer, 0, rReadShortBuffer.length); 
audioTrack.flush(); 
} 

public void endReached(){ 
.... 

} 

私の問題は、私はreachEnd()方法はaudiotrackが作成されているのと同じスレッドで実行されます期待していることです。イベントリスナーはaudiotrackに属しており、audiotrackが生成され、このスレッドでそのイベントが設定されているため、すべてのものがこのスレッドに含まれている必要があります。これは私にとって理にかなっています。しかし、プログラムはこのようにして実行されていません。 audiotrackを作成するスレッドは、run()メソッド内のすべてのコードを実行した後に終了し、mainスレッドでreachEndメソッドが実行されたようです。

あなたはこの動作の理由と、をaudiotrackを作成したスレッドと同じスレッドで実行させる理由を知っていますか?どんな助けでも大歓迎です!

+0

リスナーイベント(endReached)にデバッグできるため、再生がマーカーに到達しました。しかし、私は現在のスレッドがメインのUIスレッドにあることを発見しました。おそらく、audiotrackを作成するスレッドは、すべてのコードがrunメソッドで実行され、ブロックされないようにするためのループやスリープがないと終了している可能性があります。 – user1870797

+0

@pskink、audiotrackを作成したスレッドは、runメソッドの最後まで実行されるとすぐに終了すると思いますか?そのため、再生イベントが発生すると、システムはaudiotrackを作成した元のスレッドを見つけることができないため、イベントをメインUIスレッドに送ります。 – user1870797

+0

@pskink、ネットワークに問題があるようです。私はpastebin.comにアクセスできません。今私はハンドラとルーパーを使用して管理しています。私はそれが完了したら、結果についてあなたに教えてくれるでしょう。 – user1870797

答えて

1

スレッドにはルーパがありません(HandlerThreadなど)。ドキュメントがこれを述べるものではないがAudioTrackを作成し、あなたのスレッドがLooperを持っていない場合 は、AudioTrackイベントはメインスレッドのHandler上でスケジュールされることを意味メインルーパーを使用し、メインスレッド上で起動されます。

+0

私の場合、そのイベントはaudiotrackを作成したスレッドと同じスレッドで発生することがあります。これにより、スレッドが再生イベントが発生したときにスレッドが終了したので、システムはメインUIスレッドにイベントを渡します。このスレッドのルーパーを設定する方法の詳細を教えてください。私はちょっとこのアイデアを実装する方法を混同しています。 – user1870797

+0

audiotrackを作成したスレッドに設定するのは正しいですが、スレッドにLooper(yo Handlerを必要とする2番目のオーバーロードの手がかりを知ることができます。AudioTrackにはハンドラがイベントを発生させる必要があり、単純なスレッドにはHandlerがありません。 – yosriz

+0

これを行う方法については、handler/looperを読んでください。上で示唆したようにHandlerThreadを使用して、ルーパーでスレッドを作成することができます。 基本的にルーパー/ハンドラは、スレッドにメッセージキューがあり、このスレッドの各アクションが順番にキューに到着したことを意味します。これはmain/UIスレッドが動作する方法で、このように動作するバックグラウンドスレッドが必要です。 – yosriz

関連する問題