2017-02-16 4 views
0

Я запускаю новый поток для воспроизведения аудио. В начале метода запуска я сначала создаю audiotrack. Затем я установил audioTrack.setPlaybackPositionUpdateListener, чтобы сделать некоторые вещи, когда audiotrack закончил воспроизведение аудио. В конце концов я звоню 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(), а затем reachEnd метод выполняется в потоке main.

Вы, ребята, знаете причину этого поведения и как сделать endReached уволенными в том же потоке, что и созданный audiotrack? Любая помощь высоко ценится!

+0

Воспроизведение достигло маркера, потому что я мог отлаживать событие слушателя (endReached). Но потом я обнаружил, что текущий поток был в главной теме. Возможно, это связано с тем, что поток, создающий аудиотрек, завершился после того, как весь код был запущен в методе запуска, и нет цикла или сна, чтобы блокировать его. – user1870797

+0

@pskink, как вы думаете, поток, создавший audiotrack, будет немедленно разорван, как только он запустится до конца метода run. Поэтому, когда событие воспроизведения срабатывает, система помещает событие в основной поток ui для обработки, так как не может найти исходный поток, создавший аудиотрек. – user1870797

+0

@pskink, Кажется, что что-то не так с моей сетью. Я не могу получить доступ к pastebin.com. Прямо сейчас я могу использовать обработчик и петлитель. Я расскажу вам о результате, как только я это сделаю. – user1870797

ответ

1

Это происходит потому, что в вашей нити нет Looper (например, HandlerThread). Хотя документы не указывают это, если в вашем потоке, который создает AudioTrack, нет Looper, AudioTrack будет использовать основной петлитель, что означает, что событие будет запланировано на Handler основного потока и будет запущено в основной теме ,

+0

Я считаю, что в документе говорится, что в моем случае событие будет запущено в том же потоке, который создал аудиотрек. Возможно ли, что эта проблема вызвана тем самым поток прекращается, когда происходит событие воспроизведения. Таким образом, система передает событие основному потоку ui для обработки. Не могли бы вы объяснить мне более подробную информацию о том, как настроить петлитель для этого потока? Я думаю, что это имеет смысл, но Я немного запутался в том, как реализовать эту идею. – user1870797

+0

правильно, что она установит ее в поток, создавший аудиотрек, но не указано, что это зависит от того, имеет ли поток Looper (yo u может видеть подсказку о второй перегрузке, которая требует Handler, что AudioTrack нуждается в Handler для запуска события, а простой поток просто не имеет Handler. – yosriz

+0

Как это сделать, пожалуйста, прочитайте о обработчике/петлере, вы можете использовать HandlerThread, как было предложено выше, для создания потока с помощью петлителя. В основном Looper/Handler это означает, что поток имеет очередь сообщений, и каждое действие в этом потоке происходит последовательно, чтобы прибыть в очередь, так работает поток main/UI, вам нужен фоновый поток, который работает таким образом. – yosriz