将TTS异步初始化转换为同步

时间:2017-10-11 02:26:52

标签: java android concurrency text-to-speech

我需要从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 个答案:

答案 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合作过;希望我得到了它初始化的语义。