Android 与 HandlerThread 通信的示例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25094330/
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
Example communicating with HandlerThread
提问by CL22
I want to set up a HandlerThread from the GUI thread. Then some time later, when a button is clicked on the GUI, it runs callHello(), which then send a message to a HelloLogger object residing on the non-GUI thread which asynchronously logs "Hello World". I have tried a number of things, some block indefinitely, some never receive the message, etc etc. The code below is more or less as close as I have got, please could someone modify it to work?
我想从 GUI 线程设置一个 HandlerThread。然后一段时间后,当单击 GUI 上的按钮时,它会运行 callHello(),然后向驻留在异步记录“Hello World”的非 GUI 线程上的 HelloLogger 对象发送一条消息。我尝试了很多东西,有些无限期地阻止,有些永远不会收到消息等等。下面的代码或多或少与我所得到的一样接近,请有人修改它以使其工作吗?
public class HandlerThreadExample {
private MyHandlerThread mMyHandlerThread;
private Looper mLooper;
private Handler mHandler;
public HandlerThreadExample(){
mMyHandlerThread = new MyHandlerThread();
mMyHandlerThread.start();
mLooper = mMyHandlerThread.getLooper();
}
public void callHello() {
mHandler.sendEmptyMessage(1);
}
private class MyHandlerThread extends HandlerThread {
private HelloLogger mHelloLogger;
private Handler mHandler;
public MyHandlerThread() {
super("The MyHandlerThread thread", HandlerThread.NORM_PRIORITY);
}
public void run (){
mHelloLogger = new HelloLogger();
mHandler = new Handler(getLooper()){
public void handleMessage(Message msg){
mHelloLogger.logHello();
}
};
super.run();
}
}
private class HelloLogger {
public HelloLogger (){
}
public void logHello(){
Log.d("HandlerThreadExample", "Hello World");
}
}
}
Best examples found:
发现的最佳示例:
- HandlerThread Test
- How to create a Looper thread, then send it a message immediately?
- Async calls with Handler
- HandlerThread vs Executor - When is one more appropriate over the other?
- Best use of HandlerThread over other similar classes
- Android HandlerThread
- HandlerThread examples
- Android: Passing data between main and worker threads
- Java Synchronised
- Sending messages between threads using activity thread queue and Handler class
- Intro to Loopers and Handlers
- developer.android: Specifying the Code to Run on a Thread
- 处理线程测试
- 如何创建一个 Looper 线程,然后立即向它发送消息?
- 使用 Handler 进行异步调用
- HandlerThread 与 Executor - 什么时候哪个更合适?
- HandlerThread 在其他类似类上的最佳使用
- Android HandlerThread
- HandlerThread 示例
- Android:在主线程和工作线程之间传递数据
- Java 同步
- 使用活动线程队列和处理程序类在线程之间发送消息
- Loopers 和处理程序介绍
- developer.android:指定在线程上运行的代码
At least now I can close the damned tabs
至少现在我可以关闭该死的标签
Solution courtesy of help from pskink
解决方案由 pskink 提供帮助
public class HandlerThreadExample2 {
private static int MSG_START_HELLO = 0;
private static int MSG_HELLO_COMPLETE = 1;
private HandlerThread ht;
private Handler mHtHandler;
private Handler mUiHandler;
private boolean helloReady = false;
public HandlerThreadExample2(){
ht = new HandlerThread("The new thread");
ht.start();
Log.d(App.TAG, "UI: handler thread started");
mUiHandler = new Handler(){
public void handleMessage(Message msg){
if (msg.what == MSG_HELLO_COMPLETE){
Log.d(App.TAG, "UI Thread: received notification of sleep completed ");
helloReady = true; }
}
};
mHtHandler = new Handler(ht.getLooper()){
public void handleMessage (Message msg){
if (msg.what == MSG_START_HELLO){
Log.d(App.TAG, "handleMessage " + msg.what + " in " + Thread.currentThread() + " now sleeping");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(App.TAG, "Woke up, notifying UI thread...");
mUiHandler.sendEmptyMessage(MSG_HELLO_COMPLETE);
}
}
};
}
public void sendLongHello(){
if (helloReady){
Log.d(App.TAG, "sending hello " + Thread.currentThread());
mHtHandler.sendEmptyMessage(MSG_START_HELLO);
helloReady = false;
} else {
Log.e(App.TAG, "Cannot do hello yet - not ready");
}
}
}
回答by pskink
This is a working example:
这是一个工作示例:
HandlerThread ht = new HandlerThread("MySuperAwesomeHandlerThread");
ht.start();
Handler h = new Handler(ht.getLooper()) {
public void handleMessage(Message msg) {
Log.d(TAG, "handleMessage " + msg.what + " in " + Thread.currentThread());
};
};
for (int i = 0; i < 5; i++) {
Log.d(TAG, "sending " + i + " in " + Thread.currentThread());
h.sendEmptyMessageDelayed(i, 3000 + i * 1000);
}
UPDATE:
更新:
Make two class fields:
创建两个类字段:
Handler mHtHandler;
Handler mUiHandler;
and try this:
试试这个:
HandlerThread ht = new HandlerThread("MySuperAwsomeHandlerThread");
ht.start();
Callback callback = new Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 0) {
Log.d(TAG, "got a meaasage in " + Thread.currentThread() + ", now sleeping... ");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "woke up, notifying ui thread...");
mUiHandler.sendEmptyMessage(1);
} else
if (msg.what == 1) {
Log.d(TAG, "got a notification in " + Thread.currentThread());
}
return false;
}
};
mHtHandler = new Handler(ht.getLooper(), callback);
mUiHandler = new Handler(callback);
mHtHandler.sendEmptyMessageDelayed(0, 3000);
You can of course get rid of Callback
interface and create two Handlers with overridden handleMessage
method...
您当然可以摆脱Callback
接口并使用重写的handleMessage
方法创建两个处理程序...
回答by Larry Schiefer
The issue you are seeing is because your outer class is using a private mHandler field and so does your HandlerThread. The outer class' field is not initialized. You don't need the inner mHandler. The outer class can crate a handler from the looper you grab right after calling start().
您看到的问题是因为您的外部类使用了私有 mHandler 字段,您的 HandlerThread 也是如此。外部类的字段未初始化。您不需要内部 mHandler。外部类可以在调用 start() 后立即从您抓取的 Looper 中创建处理程序。