在一个android服务,我已经创建线程(s)做一些后台任务。
我有一个线程需要在主线程的消息队列上发布某个任务的情况,例如一个可运行的。
有没有办法得到主线程的处理程序和post Message/Runnable到它从我的其他线程?
在一个android服务,我已经创建线程(s)做一些后台任务。
我有一个线程需要在主线程的消息队列上发布某个任务的情况,例如一个可运行的。
有没有办法得到主线程的处理程序和post Message/Runnable到它从我的其他线程?
当前回答
还有另一种简单的方法,如果你没有访问Context的权限。
1).从主循环程序创建一个处理程序:
Handler uiHandler = new Handler(Looper.getMainLooper());
2).实现一个可运行的接口:
Runnable runnable = new Runnable() { // your code here }
3).发布你的Runnable到uiHandler:
uiHandler.post(runnable);
这就是全部;-)享受线程的乐趣,但不要忘记同步它们。
其他回答
我能想到的一个方法是:
1)让UI绑定到服务。 2)暴露一个方法,就像下面一个由Binder注册你的处理程序:
public void registerHandler(Handler handler) {
mHandler = handler;
}
3)在UI线程中,绑定到服务后调用上述方法:
mBinder.registerHandler(new Handler());
4)使用服务线程中的处理程序来发布你的任务:
mHandler.post(runnable);
注意:这个答案已经得到了如此多的关注,我需要更新它。自从原来的答案被发布后,@dzeikei的评论获得了几乎和原来答案一样多的关注。这里有两种可能的解决方案:
1. 如果你的后台线程有一个Context对象的引用:
确保您的后台工作线程可以访问Context对象(可以是应用程序上下文或服务上下文)。然后在后台工作线程中这样做:
// 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. 如果你的后台线程没有(或不需要)Context对象
(@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);
压缩代码块如下所示:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// things to do on the main thread
}
});
这并不涉及传递活动引用或应用程序引用。
芬兰湾的科特林相当于:
Handler(Looper.getMainLooper()).post(Runnable {
// things to do on the main thread
})
如果你在线程中运行代码,例如延迟一些动作,那么你需要从上下文调用runOnUiThread。例如,如果你的代码在MainActivity类中,那么使用这个:
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
myAction();
}
});
如果你的方法可以从main (UI线程)或其他线程调用,你需要像这样检查:
public void myMethod() {
if( Looper.myLooper() == Looper.getMainLooper() ) {
myAction();
}
else {
}
遵循这个方法。使用这种方法,您可以简单地从后台线程更新UI。runOnUiThread工作在主(UI)线程上。我认为这个代码片段不那么复杂,而且简单,特别是对初学者来说。
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();
}
});
}
});
对于服务
在oncreate中创建一个处理程序
handler = new Handler();
然后像这样使用它
private void runOnUiThread(Runnable runnable) {
handler.post(runnable);
}