设置新语言后:在返回新的 TextToSpeech(..) 实例之前调用 TextToSpeech.onInitListener

发布于 2024-12-28 16:49:06 字数 1036 浏览 0 评论 0原文

我在 Android 上的新 TextToSpeech 实例中遇到了 onInit(..) 的意外问题。

我发现的所有代码示例都假设在调用 onOnit(..) 之前将新实例返回给调用者,以便返回值可用于访问新的 TextToSpeech实例。

更改手机的默认语言后,我的活动将重新启动(如预期),并像往常一样创建一个新的 TextToSpeech 实例。但在本例中,onInit(..) 回调在 new TextToSpeech(..) 返回实例之前被调用。 onInit(..) 中的任何设置都使用过时的实例或 null

public static void startTTS()
{   
    tts_enabled = false;    
    texttospeech = null;
    texttospeech = new TextToSpeech(starter/*context*/,new TextToSpeech.OnInitListener()
    {
        public void onInit(int status)
        {
            if(texttospeech==null) throw new RuntimeException("startTTS.onInit: texttospeech=null");

            boolean r = status==TextToSpeech.SUCCESS;
            if(r) { init_tts(); tts_enabled = true; } 
            else texttospeech = null;
        }
    }); 
}

基本上,在这个例子中,异常抛出。
我已经在华为 U8510 Android 2.3.3 和 Android 2.1 模拟器上对此进行了测试。
我预计在这里做什么?

i ran into an unexpected problem with onInit(..) for a new TextToSpeech instance on Android.

All code samples i found assume that the new instance is returned to the caller before onOnit(..) is called, so that the return value is usable to access the new TextToSpeech instance.

After changing the default language for the phone my activity is restarted (as expected) and i create a new TextToSpeech instance as usual. But in this case the onInit(..) callback is called before new TextToSpeech(..) returns the instance. Any setup in onInit(..) uses an outdated instance or null.

public static void startTTS()
{   
    tts_enabled = false;    
    texttospeech = null;
    texttospeech = new TextToSpeech(starter/*context*/,new TextToSpeech.OnInitListener()
    {
        public void onInit(int status)
        {
            if(texttospeech==null) throw new RuntimeException("startTTS.onInit: texttospeech=null");

            boolean r = status==TextToSpeech.SUCCESS;
            if(r) { init_tts(); tts_enabled = true; } 
            else texttospeech = null;
        }
    }); 
}

basically, in this example, the exeption throws.

i have tested this on a Huawei U8510 Android 2.3.3 and the emulator with Android 2.1.

what am i expected to do here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放肆 2025-01-04 16:49:06

我已经解决了这个问题,并且表明原因与假设的完全不同。我的初始化代码执行了两次,创建了两个 TextToSpeech 实例,并且两个 onInit() 交错。

初始化代码被调用两次的原因有些出人意料:

我已经为此活动设置了属性 android:launchMode="singleTask" ,文档说我得到了 onNewIntent() 而不是 onCreate() > 如果活动已经在运行。我假设,而且似乎是真的,我得到了 onNewIntent() instead onCreate() 但在某些罕见的情况下,例如在用户更改了时区,除了 onCreate() 之后,我立即收到 onNewIntent() 。我不认为这种行为是有意为之的。

I have resolved this problem and it showed, that the reason was quite different than assumed. My init-code was executed twice and two TextToSpeech instances were created and the two onInit()'s interleaved.

The reason for the init code beeing called twice is somewhat unexpected:

I have set the attribute android:launchMode="singleTask" for this activity and the documentation says that i get onNewIntent() and not onCreate() if the activity is already running. I assumed, and it seemed to be true, that i get onNewIntent() instead onCreate() but in some rare cases, e.g. after the user changed the timezone, i get onNewIntent() immedeately after and in addition to onCreate(). I don't believe that this behavior is intended.

蛮可爱 2025-01-04 16:49:06

这是一个非常奇怪的案例。

我建议使用 LOCK,如下所示:

ReentrantLock waitUntilInit = new ReentrantLock();
waitUntilInit.lock();

texttospeech = null;
    texttospeech = new TextToSpeech(starter/*context*/,new TextToSpeech.OnInitListener()
    {
        public void onInit(int status)
        {
            waitUntilInit.tryLock();
            if(texttospeech==null) throw new RuntimeException("startTTS.onInit: texttospeech=null");

            boolean r = status==TextToSpeech.SUCCESS;
            if(r) { init_tts(); tts_enabled = true; } 
            else texttospeech = null;
        }
    });

if (waitUntilInit.isLocked())
waitUntilInit.unlock();

This is a very strange case.

I suggest using a LOCK, something like this:

ReentrantLock waitUntilInit = new ReentrantLock();
waitUntilInit.lock();

texttospeech = null;
    texttospeech = new TextToSpeech(starter/*context*/,new TextToSpeech.OnInitListener()
    {
        public void onInit(int status)
        {
            waitUntilInit.tryLock();
            if(texttospeech==null) throw new RuntimeException("startTTS.onInit: texttospeech=null");

            boolean r = status==TextToSpeech.SUCCESS;
            if(r) { init_tts(); tts_enabled = true; } 
            else texttospeech = null;
        }
    });

if (waitUntilInit.isLocked())
waitUntilInit.unlock();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文