我正在开发一个仅作为服务运行的应用程序。也就是说,它没有Activity
(通常至少运行),并且在任何给定时刻,将运行的应用程序的唯一组件(通常)是服务。这意味着在屏幕锁定时使用。它已经有效了。
在这种情况下,我似乎明白服务的线程是应用程序的“主线程”,即使它不是UI线程(因为没有UI)。
问题是:如果服务使用HandlerThread
,我可以从runOnUIThread()
调用的方法调用HandlerThread
吗?这会使它从主线程运行,而不需要启动Activity
(这将涉及解锁屏幕)?
基本上我的问题是我需要使用SpeechRecognizer
,从服务中对其进行归档。
现在我的服务在Handler
上使用了HandlerThread
。当尝试从SpeechRecognizer
(间接)调用的方法初始化HandlerThread
时,我得到一个例外,因为SR必须从主线程运行。
我可以使用runOnUIThread()
吗?
我在这里看到一个类似的问题:How to invoke Speechrecognizer methods from service with no main thread or activity
但是,答案涉及从onCreate()
或onStartCommand()
调用SR,这在我的情况下是不可行的。
更新:显然,我可以不致电runOnUIThread()
,因为它是Activity
的方法。那么有没有办法在主线程上运行一些调用,在这种情况下不是UI线程?
答案 0 :(得分:2)
这个答案不是特定于语音识别器的,这就是它开始作为评论的原因,但需要更多空间来澄清......
Handler mainHandler;
public void onCreate() {
super.onCreate();
mainHandler = new Handler(); // this is attached to the main thread and the main looper
// ...
}
// anywhere in a background thread:
mainHandler.post(new Runnable() {
// ...
});
此代码创建一个附加到主线程的处理程序。从后台线程发布到此处理程序将根据需要在主线程上运行代码。
我没有使用SpeechRecognizer
所以我无法保证它会解决问题,但似乎应该这样。
我想到的文章解释了一些重要的想法The Android Event Loop。特别是它链接到这段代码,通过发布到runOnUiThread
来显示如何实现Handler
,正如我在此建议的那样:
/**
* Runs the specified action on the UI thread. If the current thread is the UI
* thread, then the action is executed immediately. If the current thread is
* not the UI thread, the action is posted to the event queue of the UI thread.
*
* @param action the action to run on the UI thread
*/
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}