在Android主线程上执行代码而不访问活动?

在Android主线程上执行代码而不访问活动?,android,multithreading,Android,Multithreading,我有一个Android服务,它启动并维护一个后台线程 有时,后台线程需要在主线程上执行回调。我不知道该怎么做 我不能调用this.runOnUiThread,因为“this”是服务的实例,而不是活动,并且服务没有runOnUiThread方法 我也不能创建或执行AsyncTask,因为AsyncTask的文档说明必须从UI线程调用构造函数和execute方法 我是否需要维护对正在使用服务的活动的引用并调用其runOnUiThread方法,或者是否有其他方法在UI线程上运行某些内容 谢谢。您的活动

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


有时,后台线程需要在主线程上执行回调。我不知道该怎么做

我不能调用this.runOnUiThread,因为“this”是服务的实例,而不是活动,并且服务没有runOnUiThread方法

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

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

谢谢。

您的活动必须能够绑定到服务

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


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

当然。看见您可以为您的服务提供一个handler对象,当服务需要在UI上运行某个可运行任务时,线程只需调用handler.post(some_Runnable_task)。这个电话。可以在这4.教程中找到一个例子:Handler。

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


如果您在Kotlin中编码,您可以与主调度器一起使用协同程序

private fun runOnUiThread(block: () -> Unit) {
    CoroutineScope(Dispatchers.Main).launch { block.invoke() }
}
当然,协同程序应该作为依赖项添加到项目中。

对于Kotlin:

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

“后台线程需要在主线程上执行回调”--为什么?服务的用户是一个活动。它需要在主线程上回调,以便更新UI元素。我想我可以在后台线程上调用它,让它负责安排UI线程回调,但是如果我可以这样做的话,对服务消费者来说会更方便。@Cruceo:哦,天哪!虽然
Messenger
是一个很好的解决方案,但您不必绑定到服务来使用它
Messenger
Parcelable
的,可以通过
startService()
发送的命令以
Intent
extra的形式发送。我认为它可能已经过时了,但在2015年末,这是推荐的方式:
Handler(Looper.getMainLooper()).post { 
    /*My task*/ 
}