我有一个多线程应用程序,其中主线程启动两个线程:
MakeRequest线程在LAN上查询打印机以请求某些数据并对其执行一些计算并将其提供给第二个线程正在侦听的队列。一旦数据在Queue中可用,QueueListener线程就会从队列中取出一条记录并启动另一个线程,即MediaPlayer线程,该线程负责根据收到的字符串播放7到8个文件。我正在使用以下代码。
MediaPlayer mp = MediaPlayer.create(context, Uri.fromFile(new File(q[voiceIndex])));
mp.setOnCompletionListener(mCompletionListener);
mp.setOnErrorListener(mErrorListener);
mp.start();
此代码在PlayMedia()方法中,在OnCompletionListener中,我有以下代码:
OnCompletionListener mCompletionListener = new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
//will be called when media player finished playing a file.
mp.release();
StartPlayingNextFile();
}
};
private void StartPlayingNextFile() {
voiceIndex++;
if (voiceIndex < q.length){
PlayMedia();
}else{
finishedPlaying = true;
}
}
当QueueListener线程启动MediaPlayer线程时我在MediaPlayer线程上使用了Join(),以便不从队列中取出另一个字符串并等到MediaPlayer完成其业务,否则我会听到重叠的声音。
现在,大多数时候一切似乎都运行良好,但MediaPlayer有时会跳过播放一些文件,因此MediaPlayer线程永远不会终止,因为OnCompletionListener永远不会调用,OnErrorListener也永远不会被调用,因为Join()永远不会释放,所以我在合理的时间过后,我们要明确地做到这一点:
@Override
public void run() {
//record the start time
timeStart = new Date().getTime();
PlayMedia();
while (!finishedPlaying){
try {
//if a reasonable time has passed break the loop
long currentTime = (new Date().getTime() - timeStart);
long elapsedSeconds = TimeUnit.MILLISECONDS.toSeconds(currentTime);
if (elapsedSeconds > 15){
break;
}
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
可以看到LogCat的日志here,其中第2行和第27行之间已跳过5个文件,即
第2行: 01-21 01:20:18.474:V / MediaPlayerService(3240):从pid 15063创建新客户端(1854),url = /mnt/sdcard/voicedata/200.wav ,connId = 1854 < / p>
第27行: 01-21 01:20:30.504:V / MediaPlayerService(3240):从pid 15063创建新客户端(1855),url = /mnt/sdcard/voicedata/constants/bell.wav ,connId = 1855
已跳过的文件是:
/mnt/sdcard/voicedata/a.wav
的 /mnt/sdcard/voicedata/b.wav
的 /mnt/sdcard/voicedata/c.wav
的 /mnt/sdcard/voicedata/d.wav
/mnt/sdcard/voicedata/e.wav
和 bell.wav 是第一个在所有这些文件之前播放的文件。
答案 0 :(得分:0)
经过严格测试后,我发现减少文件数实际上改善了MediaPlayer不会跳过任何文件的更改。