我需要从TTS引擎中检索一些信息,但引擎在使用前需要初始化。我知道TextToSpeech
会致电onInit
通知已完成。
我创建了这个助手类来将其转换为同步调用:
public class PureTTSHelper implements TextToSpeech.OnInitListener {
TextToSpeech tts;
boolean ready;
CompletableFuture<TextToSpeech> completableFuture;
public PureTTSHelper(Context ctx){
this.ready = false;
this.tts = new TextToSpeech(ctx, this);
}
@Override
public void onInit(int i) {
ready = true;
completableFuture.complete(tts);
}
public TextToSpeech getTTSSync(){
if(ready){
return tts;
}
completableFuture = new CompletableFuture<>();
try {
return completableFuture.get();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
}
}
TextToSpeech tts = new PureTTSHelper(this).getTTSSync();
这不起作用。我认为正在发生的是线程在return completableFuture.get()
上被阻塞并且永远没有机会执行completableFuture.complete(tts)
,但是我不太熟悉Java中的并发性如何工作所以我不确定这是不是确切的原因。
然而,我完全不知道如何使这项工作。欢迎任何想法。
似乎初始化并不像我想象的那样完全异步。代码
TextToSpeech tts = new PureTTSHelper(this).getTTSSync();
在活动的onCreate
中执行,TextToSpeech
对象在onCreate
方法返回之前不会被初始化。
答案 0 :(得分:0)
我的第一反应是使用CountDownLatch
初始化1
来解决此问题。
public class PureTTSHelper implements TextToSpeech.OnInitListener {
TextToSpeech tts;
CountDownLatch latch;
public PureTTSHelper(Context ctx){
this.latch = new CountDownLatch(1);
this.tts = new TextToSpeech(ctx, this);
}
@Override
public void onInit(int i) {
latch.countDown();
}
public TextToSpeech getTTSSync(){
try {
latch.await();
return tts;
} catch (InterruptedException e) {
// TODO
}
}
}
我从未与TextToSpeech
合作过;希望我得到了它初始化的语义。