// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
2. If your background thread does not have (or need) a Context object
(由@dzeikei建议):
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
//code you want to run on the background
someCode();
//the code you want to run on main thread
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
/*the code you want to run after the background operation otherwise they will executed earlier and give you an error*/
executeAfterOperation();
}
});
}
});
12 回答
注意:这个答案引起了很多关注,我需要更新它 . 自从原始答案发布以来,@ dzeikei的评论几乎与原始答案一样受到关注 . 这里有两个可能的解决方案:
1. If your background thread has a reference to a Context object:
确保后台工作线程有权访问Context对象(可以是Application上下文或Service上下文) . 然后在后台工作线程中执行此操作:
2. If your background thread does not have (or need) a Context object
(由@dzeikei建议):
正如下面的评论者指出的那样,这不是服务的一般解决方案,仅适用于从您的活动启动的线程(服务可以是这样的线程,但不是所有这些线程) . 关于服务活动沟通的复杂主题,请阅读官方文档的整个服务部分 - 它很复杂,因此理解基础知识是有益的:http://developer.android.com/guide/components/services.html#Notifications
以下方法可以在最简单的情况下工作 .
如果我理解正确,你需要在应用程序的GUI线程中执行一些代码(不能考虑其他任何称为"main"线程的东西) . 为此,
Activity
上有一个方法:Doc:http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29
希望这是你正在寻找的 .
如果您无法访问Context,还有另一种简单的方法 .
1) . 从主循环器创建一个处理程序:
2) . 实现Runnable接口:
3) . 将Runnable发布到uiHandler:
这就是全部;-)享受线程的乐趣,但不要忘记同步它们 .
如果您在一个线程中运行代码,例如延迟一些动作,然后你需要从上下文中调用
runOnUiThread
. 例如,如果您的代码在MainActivity
类中,那么使用:如果您的方法可以从main(UI线程)或其他线程调用,则需要检查:
精简代码块如下:
这不涉及传递Activity引用或Application引用 .
Kotlin等效物:
我能想到的一种方法是:
1)让UI绑定到服务 .
2)通过注册
Handler
的Binder
公开类似下面的方法:3)在UI线程中,绑定到服务后调用上面的方法:
4)使用Service的线程中的处理程序发布您的任务:
HandlerThread
是Android中普通java线程的更好选择 .创建HandlerThread并启动它
使用HandlerThread创建Handler Looper:
requestHandler
859
post
Runnable
任务requestHandler
来自
HandlerThread
的UI线程通信为主线程创建
Handler
Looper
:responseHandler
并覆盖handleMessage
方法其他线程的
Runnable
任务(本例中为HandlerThread
),在responseHandler
上调用sendMessage
sendMessage
sendMessage
的sendMessage
结果调用responseHandler
.从
Message
获取属性并处理它,更新UIExample :使用从Web服务收到的数据更新
TextView
. 由于应在非UI线程上调用Web服务,因此为网络操作创建了HandlerThread
. 从Web服务获取内容后,将消息发送到主线程(UI线程)处理程序,Handler
将处理消息并更新UI .示例代码:
实用文章:
handlerthreads-and-why-you-should-be-using-them-in-your-android-apps
android-looper-handler-handlerthread-i
请遵循此方法 . 使用这种方式,您只需从后台线程更新UI . runOnUiThread在主(UI)线程上工作 . 我认为这段代码片段不那么复杂和简单,特别是对初学者而言 .
在服务的情况下
在oncreate中创建一个处理程序
然后像这样使用它
我知道这是一个老问题,但我遇到了一个主线程单线程,我在Kotlin和Java中都使用过 . 这可能不是服务的最佳解决方案,但是为了调用会改变片段内部UI的内容,这非常简单明了 .
Java(8):
科特林:
这也可以在没有问题的服务类中工作 .
对于Kotlin,你可以使用Anko corountines:
update
deprecated
最简单的方法,特别是如果你没有上下文,如果你使用RxAndroid,你可以这样做: