[英]Occasionally, Android SoundPool used with ScheduledExecutorService stops playing sounds
在我的手機和仿真器上,這種情況似乎每15次發生1次。 SoundPool將播放聲音大約3秒鍾,然后停止。 在播放聲音時,我會反復收到此消息,我理解這只是意味着不能使用低延遲模式。 而且,當聲音停止時,不會再產生這些警告。
W/AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client
如果我在整個手機上使用Android顯示器,那么當聲音停止時,我總是會收到此消息,否則就不會。 沒有異常被拋出。
07-09 22:14:15.630 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7935
07-09 22:14:15.630 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7928
07-09 22:14:15.750 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7936
07-09 22:14:15.750 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7937
07-09 22:14:15.870 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7938
07-09 22:14:16.130 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7939
07-09 22:14:16.130 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7940
07-09 22:14:16.250 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7941
07-09 22:14:16.390 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7943
07-09 22:14:16.390 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7944
07-09 22:14:17.620 2601-2890/? I/AudioPolicyManager: stopOutput() output 2, stream 7, session 7942
07-09 22:14:17.620 2601-2890/? I/AudioPolicyManager: getNewOutputDevice() selected device 0
07-09 22:14:17.620 2601-2890/? I/AudioPolicyManager: setOutputDevice() output 2 device 0x0000 delayMs 40
07-09 22:14:17.620 2601-2890/? I/AudioPolicyManager: setOutputDevice() prevDevice 0x0002
07-09 22:14:17.620 2601-2890/? I/AudioPolicyManager: setOutputDevice() setting same device 0x0000 or null device for output 2
這是我創建SoundPool的方法:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
clips = new SoundPool.Builder()
.setMaxStreams(22)
.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.build())
.build();
} else {
clips = new SoundPool(22, AudioManager.STREAM_ALARM, 0);
}
我的其余代碼太大,無法發布,但我正在按以下方式加載和播放剪輯:
ScheduledExecutorService trigger = Executors.newScheduledThreadPool(3);
int e1 = clips.load(this, noteFiles.getResourceId(0,0), 1);
int[] noteIDs = {e1};
playNote = new Runnable() {
public void run() {
clips.play(noteIDs[0], realTuneVol, realTuneVol, 1, 0, 1);
}
}
clips.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
if (savedInstanceState != null) {
trigger.shutdown();
} else {
trigger.scheduleAtFixedRate(playNote, 0, 125, TimeUnit.MILLISECONDS);
}
}
}
}
});
我正在同時播放許多剪輯,因此我知道這很可能是問題所在,但是我沒有注意到播放的剪輯數量與此錯誤之間的相關性。 但是,我已經閱讀和體驗到的是,如果我嘗試播放過多的剪輯,SoundPool只會開始跳過它們,但不會一起停止。 所以我想知道這個問題是否與我要播放的剪輯無關,實際上與ScheduledExecutorService有關。 當聲音停止時,由於我沒有收到新的Log消息,因此似乎不再執行Runnable。 任何幫助是極大的贊賞。
事實證明,如此處所述,ScheduledExecutorService抑制異常。 http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/
因此,通過將整個Runnable包裝在try catch塊中,我有時發現由於程序的另一部分而發生了ArrayIndexOutOfBoundsException,從而導致了問題。
playNote = new Runnable() {
public void run() {
try{
clips.play(noteIDs[0], realTuneVol, realTuneVol, 1, 0, 1);
}
catch (Throwable th){
Log.v("ErrorInRunnable", th.toString());
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.