【问题标题】:Execute code on main thread in Android without access to an Activity?在不访问 Activity 的情况下在 Android 的主线程上执行代码?
【发布时间】:2012-06-27 06:30:55
【问题描述】:

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

后台线程不时需要对主线程进行回调。我对如何做到这一点感到困惑。

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

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

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

谢谢。

【问题讨论】:

  • "后台线程需要在主线程上做回调" -- 为什么?
  • 服务的用户是一个activity。它需要在主线程上进行回调,以便更新 UI 元素。我想我可以在后台线程上回调它并让它负责调度 UI 线程回调,但如果我能做到这一点,对服务的使用者来说会更方便。
  • @Cruceo:哦,天哪。

标签: android multithreading


【解决方案1】:

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

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

【讨论】:

【解决方案2】:

对于 Kotlin:

Handler(Looper.getMainLooper()).post { 
    /*My task*/ 
}

【讨论】:

    【解决方案3】:

    当然。见Handler。您可以为您的服务提供一个处理程序对象,并且当服务需要在 UI 线程上运行一些可运行任务时,只需调用 handler.post(some_runnable_task)。这个电话。可以在这个link找到一个例子 4.Tutorial: Handler.

    【讨论】:

      【解决方案4】:

      您的活动必须 可以绑定到服务。

      http://developer.android.com/guide/components/bound-services.html

      具体来说,看看在该页面上创建一个 Messenger。客户端 Activity 可以提供一个响应来自服务的消息的 messenger 对象,一旦收到,就使用处理程序在 UI 线程上运行任何必要的 UI 代码。

      请勿在服务中保留活动的引用。这可能会导致各种内存问题。

      【讨论】:

      • 虽然Messenger 是一个很好的解决方案,但您不必绑定到服务即可使用它。 MessengerParcelable,可以在通过 startService() 发送的命令中以 Intent 额外发送。
      【解决方案5】:

      如果您使用 Kotlin 编写代码,则可以将 coroutineMain 调度程序一起使用:

      private fun runOnUiThread(block: () -> Unit) {
          CoroutineScope(Dispatchers.Main).launch { block.invoke() }
      }
      

      无故协程应作为依赖项添加到您的项目中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-28
        • 2010-11-19
        • 1970-01-01
        • 2017-05-20
        • 1970-01-01
        相关资源
        最近更新 更多