Преобразовать асинхронную инициализацию TTS в синхронную
Мне нужно получить некоторую информацию из движка 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
метод возвращает.
1 ответ
Моя первая реакция - решить эту проблему с помощью 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
; надеюсь, я понял семантику правильной инициализации.