从另一个线程在主线程中运行代码

本文翻译自:Running code in main thread from another thread

In an android service I have created thread(s) for doing some background task. 在android服务中,我创建了用于执行某些后台任务的线程。

I have a situation where a thread needs to post certain task on main thread's message queue, for example a Runnable . 我遇到一种情况,线程需要在主线程的消息队列上发布某些任务,例如Runnable

Is there a way to get Handler of the main thread and post Message / Runnable to it from my other thread ? 有没有办法获取主线程的Handler并从其他线程向其发布Message / Runnable

Thanks, 谢谢,


#1楼

参考:https://stackoom.com/question/kflF/从另一个线程在主线程中运行代码


#2楼

One method I can think of is this: 我能想到的一种方法是:

1) Let the UI bind to the service. 1)让UI绑定到服务。
2) Expose a method like the one below by the Binder that registers your Handler : 2)通过注册您的HandlerBinder公开以下方法:

public void registerHandler(Handler handler) {
    mHandler = handler;
}

3) In the UI thread, call the above method after binding to the service: 3)在UI线程中,绑定到服务后调用上述方法:

mBinder.registerHandler(new Handler());

4) Use the handler in the Service's thread to post your task: 4)使用服务线程中的处理程序来发布您的任务:

mHandler.post(runnable);

#3楼

NOTE: This answer has gotten so much attention, that I need to update it. 注意:此答案已引起广泛关注,我需要对其进行更新。 Since the original answer was posted, the comment from @dzeikei has gotten almost as much attention as the original answer. 自从原始答案发布以来,@ dzeikei的评论几乎和原始答案一样受到关注。 So here are 2 possible solutions: 因此,这里有两种可能的解决方案:

1. If your background thread has a reference to a Context object: 1.如果您的后台线程引用了Context对象:

Make sure that your background worker threads have access to a Context object (can be the Application context or the Service context). 确保您的后台工作线程可以访问Context对象(可以是Application上下文或Service上下文)。 Then just do this in the background worker thread: 然后只需在后台工作线程中执行此操作:

// 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 2.如果您的后台线程没有(或不需要) Context对象

(suggested by @dzeikei): (由@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);

#4楼

As a commenter below pointed correctly, this is not a general solution for services, only for threads launched from your activity (a service can be such a thread, but not all of those are). 正如下面的评论者正确指出的那样,这不是针对服务的通用解决方案,仅适用于从您的活动启动的线程(服务可以是这样的线程,但并非所有都是这样的)。 On the complicated topic of service-activity communication please read the whole Services section of the official doc - it is complex, so it would pay to understand the basics: http://developer.android.com/guide/components/services.html#Notifications 关于服务活动通信的复杂主题,请阅读官方文档的整个“服务”部分-它很复杂,因此有必要了解基本知识: http : //developer.android.com/guide/components/services.html #通知

The method below may work in simpliest cases. 下面的方法可能在最简单的情况下起作用。

If I understand you correctly you need some code to be executed in GUI thread of the application (cannot think about anything else called "main" thread). 如果我对您的理解正确,那么您需要在应用程序的GUI线程中执行一些代码(不能考虑其他称为“主”线程的代码)。 For this there is a method on Activity : 为此,在Activity上有一个方法:

someActivity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
           //Your code to run in GUI thread here
        }//public void run() {
});

Doc: http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29 Doc: http : //developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29

Hope this is what you are looking for. 希望这是您想要的。


#5楼

If you run code in a thread, eg do delaying some action, then you need to invoke runOnUiThread from the context. 如果您在线程中运行代码(例如,延迟某些操作),则需要从上下文中调用runOnUiThread For example, if your code is inside MainActivity class then use this: 例如,如果您的代码在MainActivity类中,则使用以下代码:

MainActivity.this.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        myAction();
    }
});

If your method can be invoked either from main (UI thread) or from other threads you need a check like: 如果您的方法可以从主线程(UI线程)或从其他线程调用,则需要进行如下检查:

public void myMethod() {
   if( Looper.myLooper() == Looper.getMainLooper() ) {
       myAction();
   }
   else {

}

#6楼

There is another simple way, if you don't have an access to the Context. 如果您无权访问上下文,则有另一种简单的方法。

1). 1)。 Create a handler from the main looper: 从主循环器创建一个处理程序:

Handler uiHandler = new Handler(Looper.getMainLooper());

2). 2)。 Implement a Runnable interface: 实现一个Runnable接口:

Runnable runnable = new Runnable() { // your code here }

3). 3)。 Post your Runnable to the uiHandler: 将您的Runnable发布到uiHandler:

uiHandler.post(runnable);

That's all ;-) Have fun with threads, but don't forget to synchronize them. 仅此而已;-)玩弄线程,但不要忘记同步它们。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值