在Android中的主线程上执行代码而无需访问Activity?

时间:2012-06-25 23:30:48

标签: android multithreading

我有一个启动并维护后台线程的Android服务。

后台线程有时需要在主线程上进行回调。我很难过如何做到这一点。

我无法调用this.runOnUiThread,因为“this”是Service的一个实例,而不是Activity,而Service没有runOnUiThread方法。

我也无法创建或执行AsyncTask,因为AsyncTask的文档说必须从UI线程调用构造函数和execute方法。

我是否需要维护对正在使用该服务的活动的引用并调用其runOnUiThread方法,还是有另一种方法在UI线程上运行某些东西?

感谢。

6 个答案:

答案 0 :(得分:60)

如果我不能直接访问Activity(出于某种原因或其他原因),我会不时使用以下代码;

new Handler(Looper.getMainLooper()).post(mYourUiThreadRunnable);

答案 1 :(得分:9)

  

它需要主线程上的回调,以便它可以更新UI元素。

使用LocalBroadcastManager并让服务发送广播,由活动接收,这将在主应用程序线程上获取。 Here is a sample application demonstrating this

或者,使用sendBroadcast()进行“真实”广播。

或者,如你所提到的那样,使用MessengerHandler绑定,如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

应将原因协程作为依赖项添加到您的项目中。