jjzjj

Android TextToSpeech 初始化 block /卡住 UI 线程

coder 2023-12-27 原文

我写了下面的代码:

public class MainActivity extends Activity {

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
   }

   private TextToSpeech mTTS;

   @Override
   protected void onPause() {
       super.onPause();
       if (mTTS != null) {
           mTTS.stop();
           mTTS.shutdown();
       }
   }

   @Override
   protected void onResume() {
       super.onResume();
       mTTS = new TextToSpeech(getApplicationContext(),
               new TextToSpeech.OnInitListener() {
                   @Override
                   public void onInit(int status) {
                       if(status != TextToSpeech.ERROR){
                           mTTS.setLanguage(Locale.ENGLISH);
                           mTTS.speak("Hello!", TextToSpeech.QUEUE_FLUSH, null);
                       }
                   }
               });       
   }

   public void onButtonClick(View view) {
       mTTS.speak("Hello!", TextToSpeech.QUEUE_FLUSH, null);
   }
}

但是这段代码:mTTS = new TextToSpeech(... 卡住了 UI 线程 5-8 秒。

我注意到延迟发生在 logcat 的这一行(第一行):

07-13 11:51:11.304    5296-5296/com.example.TextToSpeachTest I/TextToSpeech﹕ Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
07-13 11:51:17.317    5296-5296/com.example.TextToSpeachTest I/Choreographer﹕ Skipped 391 frames!  The application may be doing too much work on its main thread.

我试着把它放在 AsyncTask 里面:

@Override
protected void onResume() {
    super.onResume();

    MyAsyncTask newTask = new MyAsyncTask() {
        protected void onPostExecute(Boolean result) {
        }
    };
    newTask.context = getApplicationContext();
    newTask.execute();
}
...

class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
    private TextToSpeech mTTS;
    public Context context;
    @Override
    protected Boolean doInBackground(Void... arg0) {
        mTTS = new TextToSpeech(context,
                new TextToSpeech.OnInitListener() {
                    @Override
                    public void onInit(int status) {
                        if(status != TextToSpeech.ERROR){
                            mTTS.setLanguage(Locale.ENGLISH);
                            mTTS.speak("Hello!", TextToSpeech.QUEUE_FLUSH, null);
                        }
                    }
                });
        return true;
    }
}

但是什么都没有改变。您能否建议一个合适的解决方案/想法?

此延迟出现在我的手机 LG L4 II (E440) 上。在 Nexus 10 上——没有延迟。 我在 LG L4 上尝试了来自 Play Store 的不同语音应用程序。在一些应用程序上也有 UI 阻塞,但有些应用程序没有阻塞。这意味着——有可能实现。但是如何呢?

最佳答案

您的代码没问题,您不需要从不同的线程调用 TextToSpeech 构造函数。

实际上,问题在于某些使用主 UI 线程进行语音处理的 TextToSpeech 库的实现。

解决方案是让 TextToSpeech 处理在一个单独的进程中运行,不同于 UI 线程的进程。这样,UI交互和语音处理是在两个不同进程的主线程中完成的。我发现这样做的唯一方法是在具有自己进程的 Android 服务中创建 TextToSpeech 对象和控制代码。

为了创建具有自己进程的服务,AndroidManifest.xml 中的配置必须包含属性:android:process:

    <service
        android:name=".TtsService"
        android:enabled="true"
        android:exported="false"
        android:process="com.example.ttsservice">
    </service>

这引入了复杂性,因为现在 Activity 必须使用 Messenger 或 AIDL (http://developer.android.com/guide/components/bound-services.html) 绑定(bind)服务以管理 TextToSpeech 功能。

关于Android TextToSpeech 初始化 block /卡住 UI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24712639/

有关Android TextToSpeech 初始化 block /卡住 UI 线程的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  3. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  4. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  5. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  6. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  7. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  8. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  9. ruby - 在匿名 block 中产生 - 2

    我没有理解以下行为(另请参阅inthisSOthread):defdef_testputs'def_test.in'yieldifblock_given?puts'def_test.out'enddef_testdoputs'def_testok'endblock_test=procdo|&block|puts'block_test.in'block.callifblockputs'block_test.out'endblock_test.calldoputs'block_test'endproc_test=procdoputs'proc_test.in'yieldifblock_gi

  10. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

随机推荐