Java Android ToneGenerator StartOne()在第一次调用时速度非常慢

Java Android ToneGenerator StartOne()在第一次调用时速度非常慢,java,android,performance,tone-generator,Java,Android,Performance,Tone Generator,我正在反复调用ToneGenerator.startTone()发出短暂的声音。但在第一次呼叫时,它会阻塞很长一段时间。所以第一次爆发的时间太长了。下面是一个例子: 成员变量: private ToneGenerator mDTMFPlayer 在构造函数中: mDTMFPlayer = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, TONE_RELATIVE_VOLUME); 在由OnClickListener.onClick()启动的

我正在反复调用
ToneGenerator.startTone()
发出短暂的声音。但在第一次呼叫时,它会阻塞很长一段时间。所以第一次爆发的时间太长了。下面是一个例子:

成员变量:

private ToneGenerator mDTMFPlayer
在构造函数中:

mDTMFPlayer = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, TONE_RELATIVE_VOLUME);
在由
OnClickListener.onClick()
启动的
线程中:

以下是输出,执行时间为
startTone()
,以毫秒为单位:

11-16 18:07:35.885 16927-17977/com.my.project D/Ring: After 1st: 454
11-16 18:07:36.502 16927-17977/com.my.project D/Ring: After 2nd: 0
11-16 18:07:36.672 16927-17977/com.my.project D/Ring: After 3rd: 1
第一个呼叫几乎被阻塞了半秒钟,这对于我所需要的来说太长了。之后的任何呼叫都会使阻塞消失一段时间。奇怪的是,如果我等一等,再试一次,它又慢了。似乎有一段时间之后,阻塞恢复


请告知。

我认为是音频管理器。流式语音呼叫造成的。我的装置上的行为和你的相似。运行应用程序后,第一次调用
startTone()
时,它有一个长init。如果我退出并进入应用程序,它可以快速处理所有3个电话。但如果在应用程序启动前播放一些系统声音,它将显示相同的“慢、快、快”结果

因此,我认为这与流切换/阻塞有关,因为使用
AudioManager.stream\u通知
在我的设备上只需4-10毫秒。也可以在此处阅读更多信息:

考虑以下代码:

for (int i = -1; i < 10; i++) {
    System.out.println("AudioSystem stream " + i);
    mDTMFPlayer = new ToneGenerator(i, TONE_RELATIVE_VOLUME);
    long startTime = System.currentTimeMillis();
    mDTMFPlayer.startTone(ToneGenerator.TONE_DTMF_0);
    Log.d(TAG, "After 1st: " + (System.currentTimeMillis() - startTime));
    try {Thread.sleep(160);} catch (InterruptedException e) {}
    mDTMFPlayer.stopTone();

    startTime = System.currentTimeMillis();
    mDTMFPlayer.startTone(ToneGenerator.TONE_DTMF_0);
    Log.d(TAG, "After 2nd: " + (System.currentTimeMillis() - startTime));
    try {Thread.sleep(160);} catch (InterruptedException e) {}
    mDTMFPlayer.stopTone();

    startTime = System.currentTimeMillis();
    mDTMFPlayer.startTone(ToneGenerator.TONE_DTMF_0);
    Log.d(TAG, "After 3rd: " + (System.currentTimeMillis() - startTime));
    try {Thread.sleep(160);} catch (InterruptedException e) {}
    mDTMFPlayer.stopTone();
    mDTMFPlayer.release();
}

顺便说一句,如果你想研究相关的C源代码,你可以看看,

一点是多长?注意,这是每个进程的问题吗,其中“一点”是在您的进程被终止并通过用户操作被重新创建之后?不,进程继续,我等待不到一秒钟,然后再次单击按钮,该按钮调用onClick(),启动一个单独的线程(我不想在GUI线程上阻塞)并调用startTone()再次说明。好的
startTone()
只是调用一个
native
方法(请参阅),因此我不确定您是否可以对此做很多事情。如果不是native,我可能已经找到了原因。:)指向很抱歉,如果我的评论有其他暗示的话,我的评论是为了下一个遇到这个问题的人,如果你没有得到答案的话。最后我使用了STREAM_DTMF,它实际上是为这个问题而设计的,没有任何延迟。完美的解决方案。谢谢你的回答。肯定会给你赏金的。
for (int i = -1; i < 10; i++) {
    System.out.println("AudioSystem stream " + i);
    mDTMFPlayer = new ToneGenerator(i, TONE_RELATIVE_VOLUME);
    long startTime = System.currentTimeMillis();
    mDTMFPlayer.startTone(ToneGenerator.TONE_DTMF_0);
    Log.d(TAG, "After 1st: " + (System.currentTimeMillis() - startTime));
    try {Thread.sleep(160);} catch (InterruptedException e) {}
    mDTMFPlayer.stopTone();

    startTime = System.currentTimeMillis();
    mDTMFPlayer.startTone(ToneGenerator.TONE_DTMF_0);
    Log.d(TAG, "After 2nd: " + (System.currentTimeMillis() - startTime));
    try {Thread.sleep(160);} catch (InterruptedException e) {}
    mDTMFPlayer.stopTone();

    startTime = System.currentTimeMillis();
    mDTMFPlayer.startTone(ToneGenerator.TONE_DTMF_0);
    Log.d(TAG, "After 3rd: " + (System.currentTimeMillis() - startTime));
    try {Thread.sleep(160);} catch (InterruptedException e) {}
    mDTMFPlayer.stopTone();
    mDTMFPlayer.release();
}
I/System.out: AudioSystem stream -1 STREAM_DEFAULT
D/com.example.MainActivity: After 1st: 8
D/com.example.MainActivity: After 2nd: 1
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 0 STREAM_VOICE_CALL
D/com.example.MainActivity: After 1st: 325
D/com.example.MainActivity: After 2nd: 1
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 1 STREAM_SYSTEM
D/com.example.MainActivity: After 1st: 17
D/com.example.MainActivity: After 2nd: 2
D/com.example.MainActivity: After 3rd: 3
I/System.out: AudioSystem stream 2 STREAM_RING
D/com.example.MainActivity: After 1st: 28
D/com.example.MainActivity: After 2nd: 2
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 3 STREAM_MUSIC
D/com.example.MainActivity: After 1st: 19
D/com.example.MainActivity: After 2nd: 1
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 4 STREAM_ALARM
D/com.example.MainActivity: After 1st: 28
D/com.example.MainActivity: After 2nd: 1
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 5 STREAM_NOTIFICATION
D/com.example.MainActivity: After 1st: 16
D/com.example.MainActivity: After 2nd: 1
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 6 STREAM_BLUETOOTH_SCO
D/com.example.MainActivity: After 1st: 332
D/com.example.MainActivity: After 2nd: 2
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 7 STREAM_SYSTEM_ENFORCED
D/com.example.MainActivity: After 1st: 324
D/com.example.MainActivity: After 2nd: 1
D/com.example.MainActivity: After 3rd: 1
I/System.out: AudioSystem stream 8 STREAM_DTMF
D/com.example.MainActivity: After 1st: 26
D/com.example.MainActivity: After 2nd: 2
D/com.example.MainActivity: After 3rd: 4
I/System.out: AudioSystem stream 9 STREAM_TTS
D/com.example.MainActivity: After 1st: 12
D/com.example.MainActivity: After 2nd: 4
D/com.example.MainActivity: After 3rd: 2