Java Android:为什么我不能在新线程中创建处理程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18856376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: Why can't I create a handler in new thread
提问by nguyenbkcse
I had a problem creating a handler in new thread. This is my code:
我在新线程中创建处理程序时遇到问题。这是我的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
public void run() {
Handler handler = new Handler();
}
}).start();
}
But it raised an error! Can someone please explain this to me? Thanks so much!
但它引发了一个错误!有人可以向我解释一下吗?非常感谢!
Here are the details of my error:
以下是我的错误的详细信息:
09-17 18:05:29.484: E/AndroidRuntime(810): FATAL EXCEPTION: Thread-75
09-17 18:05:29.484: E/AndroidRuntime(810): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-17 18:05:29.484: E/AndroidRuntime(810): at android.os.Handler.<init>(Handler.java:197)
09-17 18:05:29.484: E/AndroidRuntime(810): at android.os.Handler.<init>(Handler.java:111)
09-17 18:05:29.484: E/AndroidRuntime(810): at com.example.handler.MainActivity.run(MainActivity.java:57)
09-17 18:05:29.484: E/AndroidRuntime(810): at java.lang.Thread.run(Thread.java:856)
采纳答案by Alex Lockwood
You could also use a HandlerThread
like this:
你也可以使用HandlerThread
这样的:
HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();
Handler handler = new Handler(thread.getLooper());
HandlerThread
s have a Looper
associated with them, so this wouldn't throw an exception.
HandlerThread
sLooper
与它们相关联,因此这不会引发异常。
回答by nandeesh
The Thread's lifecycle
is finished right after run method returns. But since you are creating a Handler
in this thread
, the Handler needs the thread to be running for it to receive messages and process them.
线程lifecycle
在 run 方法返回后立即完成。但是由于您Handler
在 this中创建 a thread
,处理程序需要运行线程以接收消息并处理它们。
So for this to happen, run method should not exit. Hence you need a Looper to wait indefinitely and process messages that arrive to Handler.
因此,要发生这种情况,run 方法不应退出。因此,您需要一个 Looper 无限期地等待并处理到达 Handler 的消息。
new Thread(new Runnable() {
public void run() {
Looper.prepare();
Handler handler = new Handler();
Looper.loop();
}
}).start();
回答by FunkTheMonk
A Handler needs to be initialised in a Looper thread, or have a Looper given to it.
Handler 需要在 Looper 线程中初始化,或者给它一个 Looper。
Depending on what you want to do, you can set up your thread to be a Looper like so:
根据您想要做什么,您可以将您的线程设置为 Looper,如下所示:
new Thread(new Runnable() {
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}).start();
Since the Looper is in a background thread, you cannot update the UI. You could alternativly give the Handler a Looper from another thread - in this example, the Handler can be used to update the UI:
由于 Looper 在后台线程中,您无法更新 UI。你也可以从另一个线程给 Handler 一个 Looper - 在这个例子中,Handler 可以用来更新 UI:
new Thread(new Runnable() {
public void run() {
Handler handler = new Handler(Looper.getMainLooper());
}
}).start();
回答by Jai Pandit
Short Answer: Because the thread you're trying to attach the Handler on, doesn't have a looper. And so the constructor of Handler class is throwing exception. You could have used a HandlerThread class instead, This is just a handy class provided by the Android framework.
简短回答:因为您尝试将 Handler 附加到的线程没有活套。所以Handler类的构造函数抛出异常。您可以改用 HandlerThread 类,这只是 Android 框架提供的一个方便的类。
Please read below for whats happening under the hood.
请阅读下面的内容,了解幕后发生的事情。
Lets first try to discuss all parts individually.
让我们首先尝试单独讨论所有部分。
- Thread:
- 线:
a. A thread is just a execution flow. A thread by default is suppose to just execute its runnable(if provided) or call its run method. Upon calling new Thread.start(). A thread just dies and Gc'd when the run method executes all the statement written inside the run(){ ---- }.
一种。线程只是一个执行流。默认情况下,线程假设只执行其可运行的(如果提供)或调用其 run 方法。在调用 new Thread.start() 时。当 run 方法执行 run(){ ---- } 中写入的所有语句时,一个线程就会死亡并被 Gc'd。
b. There is a concept of Looper in Android. Which basically makes the thread a blocking thread. Putting simply it just doesn't let the thread die. It goes in a blocking state and waiting for more messages to again resume its execution.
湾 Android中有一个Looper的概念。这基本上使线程成为阻塞线程。简单地说,它不会让线程死亡。它进入阻塞状态并等待更多消息再次恢复执行。
Below is how you'd setup a blocking thread i.e a thread with a looper.
下面是如何设置阻塞线程,即带有循环程序的线程。
new Thread(new Runnable() {
public void run() {
Looper.prepare();
Looper.loop();
}
}).start();
Here a thread is created which doesn't just die after executing the Looper.loop() statement. Instead it loops and goes in a blocking state. Now you must be asking what is the meaning of blocking state, how the thread will come out of the blocking state ? how do i finally release this thread now ? This is where Handler comes in
这里创建了一个线程,该线程不仅在执行 Looper.loop() 语句后死亡。相反,它循环并进入阻塞状态。现在你肯定会问阻塞状态是什么意思,线程如何脱离阻塞状态?我现在如何最终发布这个线程?这就是 Handler 的用武之地
- Handler:
- 处理程序:
a. It always attaches itself to the Looper of the thread, on which its instance is created.
一种。它总是将自己附加到线程的 Looper 上,在该线程上创建其实例。
b. It then processes those messages of the thread it attaches to.
湾 然后它处理它附加到的线程的那些消息。
Putting together thread and handlers.
将线程和处理程序放在一起。
new Thread(new Runnable() {
public void run() {
Looper.prepare();
handler = new Handler();
Looper.loop();
}
}).start();
a. How the handler gets attached to this newly created thread. b. The thread is setup as a blocking looper thread. So this is not going to die.
一种。处理程序如何附加到这个新创建的线程。湾 该线程被设置为阻塞循环线程。所以这不会死。
now, we can 1. Send message on this handler. 2. Post runnable on this handler.
现在,我们可以 1. 在此处理程序上发送消息。2. 在此处理程序上发布可运行。
Both of them will be executed on the attached thread.
它们都将在附加的线程上执行。
You have an option to either extend the Handler class and implement method handleMessage(Message msg). or you just provide implementation of the Handler.Callback in the constructor of the handler class. In either way the handleMessage(Messages msg) will be called on the attached thread.
您可以选择扩展 Handler 类并实现方法 handleMessage(Message msg)。或者您只是在处理程序类的构造函数中提供 Handler.Callback 的实现。无论哪种方式,都将在附加线程上调用 handleMessage(Messages msg)。
To quit the thread you can send a specific type of message type, and upon receiving that message you'd just call Looper.myLooper().quit()
要退出线程,您可以发送特定类型的消息类型,并在收到该消息后调用 Looper.myLooper().quit()
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
if(msg.what == -1){
Looper.myLooper().quit();
}
}
};
Looper.loop();
}
}
I hope it helped understanding the overall concept.
我希望它有助于理解整体概念。