Reputation: 618
In Android system there is TextToSpeech API that allows initialize TTS engine - it happens by calling TextToSpeech constructor and giving listener called later with result:
mEngine = new TextToSpeech(mContext, listener, ENGINE_GOOGLE_NAME);
What I want to reach is to have one blocking function that calls constructor and returns after callback is done.
As I experienced no matter from what thread the constructor is called, the listener is fired from "main" application's thread.
My idea was to have example function (simplified code - I hope it is understandable):
private TextToSpeech mEngine;
CountDownLatch cdl = new CountDownLatch(1);
ExecutorService executorService = Executors.newSingleThreadExecutor();
public void initializeBlocking() {
executorService.execute(() -> { // new thread
mEngine = new TextToSpeech(mContext, status -> {
cdl.countDown(); // callback body (executes in "main" thread)
}, ENGINE_GOOGLE_NAME);
});
cdl.await(); // main thread
}
I hoped the listener also will be called in new thread, but since it is called in main thread and main thread is waiting ( cdl.await() ) it is never called and whole application is getting stuck.
Do you have any idea how can I reach my goal in this situation? Maybe I am doing something basically wrong?
Upvotes: 0
Views: 38
Reputation: 10621
TextToSpeech
uses an AsyncTask
internally, which calls its onPostExecute
method on the main thread. This is why the callback runs on the main thread.
On the other hand, you should not block the main thread waiting for the initialization to complete. TextToSpeech
needs to download voice data, which can take a while.
If your main thread is blocked for a few seconds the OS will show a dialog to the user suggesting to close the app.
Upvotes: 0