Initialising the TextToSpeech object on a worker t

2020-02-01 04:17发布

问题:

For years (literally), my application has suffered woes from poorly performing text to speech engines, in particular, the initialisation time when calling:

tts = new TextToSpeech(context, myOnInitListener);

The above can cause the UI to lag and if you search for 'Text to Speech initialization slow' on SO, you'll find many posts. The embedded high quality IVONA voices used to be the worst culprit, but the Google TTS engine has now taken the prize.

Their most recent APK update, causes major lag on initialisation - No code necessary to test this, you can go to your Android Text to Speech settings and try switching between available engines, whilst pressing 'listen to a sample', the lag is demonstrated 'nicely'.

To try and combat this, I've implemented the following:

private volatile TextToSpeech tts;

AsyncTask.execute(new Runnable() {
    @Override
    public void run() {
        tts = new TextToSpeech(context, volatileOnInitListener);
    }
});

This has completely cured the lag on initialisation, but I fear there may be side-effects to this that I've not considered? Can anyone think of any?

I'm puzzled also, as I had believed the the TextToSpeech Constructor was asynchronous and therefore moving this constructor to a worker thread should make no difference? If this implementation is the way forward, then why don't Google implement it in their TextToSpeechSettings?

Hope someone can clarify the above. Thanks in advance.

Edit - When I said the 'Constructor was asynchronous', I really was referring to the engine initialisation process it starts, and the eventual call to onInit

回答1:

I had believed the the TextToSpeech Constructor was asynchronous

That is only partially true. A lot of the initialization is executed syncronously. Here is the Source

If this implementation is the way forward, then why don't Google implement it in their TextToSpeechSettings?

It seems like google seldomly checks how their code runs on mid and lowend devices, I guess the lag doesn't show on highend devices. (Another example of this happening can be seen in the current youtube app, for which I personally can confirm lag on a mid-spec device and no lag on a high-end device.) This is pure speculation as I am not affiliated to google.

I fear there may be side-effects to this that I've not considered? Can anyone think of any?

The only (obvious) sideeffect is that you can't use the tts engine syncronously, but have to wait for the asyncronous task to finish. But that is already the case anyway. The only thing you do is execute some code outside of the UI thread, which does not expect to be run on the UI thread. This should never be a problem. And even if there is a problem, you will only find it by testing it in an application.

In general you're good to go.