批量合成TTS音频后更新UI触发Looper线程错误求助
解决"Animators may only be run on Looper threads"错误
这个问题的核心原因很明确:UtteranceProgressListener的回调方法(比如OnDone)是在后台线程执行的,而Android要求所有UI操作必须在主线程(UI线程)中完成。你之前尝试把FAB设为全局变量没用,就是因为操作它的线程还是不对,和变量是否全局无关。
具体解决方案:切换到主线程执行UI操作
你可以利用Activity的RunOnUiThread方法,把更新UI的逻辑包裹在里面,确保代码在主线程运行。下面是修改后的关键代码:
1. 修改UtteranceProgressListener1的OnDone方法
把调用AudioConvertionResults的逻辑放到RunOnUiThread中:
public override void OnDone(String utteranceId) { Log.Info("101029", "OnDone: " + total.ToString()); total++; // 切换到主线程执行UI相关的检查和操作 _parent.RunOnUiThread(() => { _parent.AudioConvertionResults(total); }); }
2. 确保AudioConvertionResults中的UI操作安全
虽然上面已经切换了线程,你也可以简化这个方法,直接在主线程里处理:
public bool AudioConvertionResults(int CompInt) { Log.Info("101029", "ComInt: " + CompInt.ToString() ); if (CompInt >= 10) { try { Log.Info("101029", "Triggered at " + CompInt.ToString()); FloatingActionButton FAB = FindViewById<FloatingActionButton>(Resource.Id.fab); FAB.Visibility = ViewStates.Visible; } catch(Exception X) { Log.Info("101029", "Error Triggering? "+X.Message); return false; } return true; } else { Log.Info("101029", "DID NOT Trigger at " + CompInt.ToString()); return false; } }
为什么这样能解决问题?
RunOnUiThread会把传入的Action提交到主线程的消息队列中,等待主线程空闲时执行,这样所有的UI操作(比如查找控件、设置可见性)就都在正确的线程上运行了,自然就不会再出现"Animators may only be run on Looper threads"的错误。
另外,如果你习惯用Handler,也可以创建一个主线程的Handler来发送消息处理UI操作,效果是一样的,不过RunOnUiThread在Activity中使用更简洁。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

