我有一个启动并维护后台线程的Android服务。
后台线程有时需要在主线程上进行回调。我很难过如何做到这一点。
我无法调用this.runOnUiThread,因为“this”是Service的一个实例,而不是Activity,而Service没有runOnUiThread方法。
我也无法创建或执行AsyncTask,因为AsyncTask的文档说必须从UI线程调用构造函数和execute方法。
我是否需要维护对正在使用该服务的活动的引用并调用其runOnUiThread方法,还是有另一种方法在UI线程上运行某些东西?
感谢。
答案 0 :(得分:60)
如果我不能直接访问Activity(出于某种原因或其他原因),我会不时使用以下代码;
new Handler(Looper.getMainLooper()).post(mYourUiThreadRunnable);
答案 1 :(得分:9)
它需要主线程上的回调,以便它可以更新UI元素。
使用LocalBroadcastManager
并让服务发送广播,由活动接收,这将在主应用程序线程上获取。 Here is a sample application demonstrating this
或者,使用sendBroadcast()
进行“真实”广播。
或者,如你所提到的那样,使用Messenger
与Handler
绑定,如Guillermo所提到的,尽管你不一定需要使用绑定。
答案 2 :(得分:2)
您的活动必须 可以绑定到该服务。
http://developer.android.com/guide/components/bound-services.html
具体来说,请看一下在该页面上创建Messenger。客户端活动可以提供响应来自服务的消息的messenger对象,一旦收到,就使用处理程序在UI线程上运行任何必要的UI代码。
不要保留活动在服务中的引用。这可能会导致各种内存问题。
答案 3 :(得分:1)
不确定。见Handler。您可以为您的服务提供一个处理程序对象,当服务需要在UI线程上运行一些Runnable任务时,必须调用handler.post(some_runnable_task)。这个电话。可以在这个link 4.Tutorial:Handler。
中找到一个例子答案 4 :(得分:1)
对于Kotlin:
import { useIsFocused } from "react-navigation-hooks";
...
const [showGallery, setShowGallery] = useState(true);
...
useEffect(() => {
if (isFocused) {
setShowGallery(true);
} else {
setShowGallery(false);
}
console.log("isFocused: " + isFocused);
}, [isFocused]);
答案 5 :(得分:0)
如果您使用Kotlin进行编码,则可以将协程与 Main 调度程序配合使用:
std::find
应将原因协程作为依赖项添加到您的项目中。