【问题标题】:TTS and Singleton in AndroidAndroid 中的 TTS 和 Singleton
【发布时间】:2019-10-25 14:11:34
【问题描述】:

我有一个应用程序非常频繁地使用 TTS。它工作正常,但我需要对其进行调整。

我在每个屏幕中都使用 TTS 对象,这并不好。我希望我可以只创建一次 TTS 对象(如 Singleton),然后在我的所有活动中使用它。

这是它的基本代码:

    public class SimOuNaoActivity extends Activity implements OnInitListener{
    public TextToSpeech tts;
        private int MY_DATA_CHECK_CODE = 0;


        @Override
        public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);
    Intent checkIntent = new Intent();
    checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
    startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
    tts.speak("Testing 1,2,3", TextToSpeech.QUEUE_ADD, null);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_DATA_CHECK_CODE) {
        if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
            tts = new TextToSpeech(this, this);
        } else {
            // missing data, install it
            Intent installIntent = new Intent();
            installIntent
                    .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
            startActivity(installIntent);
        }
    }

}

@Override
public void onInit(int status) {
    if (status == TextToSpeech.SUCCESS) {
        // Toast.LENGTH_LONG).show();
    } else if (status == TextToSpeech.ERROR) {
        // Toast.LENGTH_LONG).show();
    }
}

@Override
public void onDestroy() {
    if (tts != null) {
        tts.stop();
        tts.shutdown();
    }
    super.onDestroy();
       System.gc();
    }

    }

在我的所有活动中使用 TTS 对象的正确方法是什么?请记住,它使用了一些方法,如 startActivityForResult 等......所以......我想知道我能做些什么来使这项工作正常。

有人可以帮帮我吗?

感谢任何帮助!

谢谢!

【问题讨论】:

  • 那么,是什么阻止您将 TextToSpeech 对象设置为 Singleton?在您的用例中听起来像是一件明智的事情。您可以在自己的 Application 子类中设置它,以便从所有活动中轻松访问它,或者,也许更方便的是,使用相关方法创建某种基本活动,这些方法将调用从 Singleton/Application 委托给 TextToSpeech 对象,并拥有所有其他活动扩展了这一点。
  • 你好MH,谢谢你的回答。任何示例代码?我有点卡在这里=P
  • 这里不要复制粘贴代码,我建议你看看this almost identical topic。另一个使用单例模式的 TTS 实现可以在here 找到。请注意,使用Singleton vs. Application 并没有真正达成共识。我会把这个决定留给你。祝你好运。 :)

标签: android singleton text-to-speech


【解决方案1】:

这比较简单 - 只需按如下方式实现,不要忘记将应用程序上下文 (this.getApplicationContext()) 作为上下文传递,而不是活动上下文。

public class SingletonTTS {

private static SingletonTTS instance;
private static Context ctx;
private TextToSpeech mTTS;
private static boolean TTSready = false;

private SingletonTTS(Context context) {
    ctx = context;
    mTTS = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int i) {
            TTSready = true;
            configTTS();

        }
    });
}

public static synchronized SingletonTTS getInstance(Context context) {
    if (instance == null) {
        instance = new SingletonTTS(context);
    }
    return instance;
}

public static boolean isTTSready(){
    return TTSready;
}

private void configTTS() {
    Toast.makeText(ctx, "supports " + mTTS.isLanguageAvailable(Locale.getDefault()), Toast.LENGTH_LONG).show();
    int available = mTTS.isLanguageAvailable(Locale.getDefault());
    if( available != TextToSpeech.LANG_MISSING_DATA
            && available != TextToSpeech.LANG_NOT_SUPPORTED ){
        mTTS.setLanguage(new Locale(Locale.getDefault().getLanguage()) );

    } else {
        /** TODO SAVE */
    }

}

public void speakSentence(String sentence){
    mTTS.speak(sentence, TextToSpeech.QUEUE_ADD, null);
}

}

【讨论】:

  • 应用上下文和活动上下文是一回事。那是因为Activity扩展了ContextWrapper,也就是实现getApplicationContext的类
  • 它们都是Context的实例,但是应用实例与应用的生命周期绑定,而Activity实例与Activity的生命周期绑定。因此,他们可以访问有关应用程序环境的不同信息。
  • 是的,当然-我认为您应该编辑答案的最后一部分以更清楚您的意思-“而不是活动context”->“而不是活动实例"
【解决方案2】:

查看这里以在 android 中以更好的设计在活动和程序之间共享内容: Intent.putExtras size limit?

【讨论】:

    【解决方案3】:

    您可能希望在应用程序中实例化并保存单例对象,无论如何它只能实例化一次,因此只需将您的 TTS 初始化代码放在它自己的一个类中,然后将该类实例化为您的应用程序中的一个对象.您需要将 Application 作为实例化 TTS 的 Context 传递给您的 TTS 类。

    public class MyApplication extends Application {
        public MyTTS myTTS;
        public void onCreate() {
            myTTS = new MyTTS(this);
        }
    }
    

    然后您可以在活动中使用 getApplication().myTTS.whateverMethodsYouMake(yadayada) 来访问 Application-Singleton-ified TTS 类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-07
      • 1970-01-01
      • 2016-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多