我的测试应用程序大致基于Cristian Baita的threads tutorial。 它按预期工作,但是从myThread的run()方法发送的消息永远不会被MainActivity的处理程序接收。
我将MainActivity的处理程序传递给线程构造函数中的myThread。然后我使用该处理程序的sendMessage()方法将消息发送回MainActivity,但处理程序似乎永远不会收到它。这是为什么?
注意:我发现在eclipse中使用断点进行调试对于线程来说很麻烦,所以我最终使用Log语句来查看顶部,以帮助跟踪应用程序的执行。
我已将完整代码放在本文末尾,但总结一下:
MyThread类的构造函数从调用活动中获取一个处理程序,如下所示。
public class MyThread extends Thread {
// Reference to mainHandler from the mainThread
private Handler parentHandler;
// Constructor
public MyThread(Handler pHandler) {
parentHandler = pHandler;
}
当我在MainActivity的onCreate()方法中创建线程时,我将处理程序mainHandler
传递给它:
myThread = new MyThread(mainHandler);
myThread.start();
然后在MyThread的run()方法中我有:
Message messageToParent = Message.obtain();
messageToParent.what = 2;
Log.i("myThread", "About to send message to parent ...");
parentHandler.sendMessage(messageToParent);
然后应该通过MainActivity中定义的mainHandler
接收消息:
public Handler mainHandler = new Handler() {
public void handleMessages(Message msg){
Log.i("MainActivity", "Message Received");
switch(msg.what) {
case 2:
Log.i("MainActivity", "Handled message. msg.what = " + msg.what);
....
如果在运行LogCat窗口时观察它,您将看到MainActivity从不记录“已接收消息”或“已处理消息...”。所以消息永远不会到达它的目的地。
MainActivity:
public class MainActivity extends Activity {
private MyThread myThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myThread = new MyThread(mainHandler);
myThread.start();
// Message the thread
Message msgToThread = Message.obtain();
msgToThread.what = 4;
Log.i("MainActivity", "About to send message to thread...");
myThread.getHandler().sendMessage(msgToThread);
}
public Handler mainHandler = new Handler() {
public void handleMessages(Message msg){
Log.i("MainActivity", "Message Received");
switch(msg.what) {
case 2:
Log.i("MainActivity", "Handled message. msg.what = " + msg.what);
// Message the thread
Message msgToThread = Message.obtain();
msgToThread.what = 6;
myThread.getHandler().sendMessage(msgToThread);
break;
default:
Log.i("MainActivity", "Unhandled message. msg.what = " + msg.what);
break;
}
}
};
}
MyThread类:
public class MyThread extends Thread {
// Reference to mainHandler from the mainThread
private Handler parentHandler;
// Constructor
public MyThread(Handler pHandler) {
parentHandler = pHandler;
}
// Local handler for messages to this thread
private Handler myThreadHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what) {
case 4:
Log.i("myThread", "Handled message. msg.what = " + msg.what);
break;
case 6:
Log.i("myThread", "Handled message. msg.what = " + msg.what);
break;
default:
Log.i("myThread", "Unhandled message. msg.what = " + msg.what);
break;
}
}
};
@Override
public void run() {
super.run();
int count = 0;
boolean keepGoing = true;
try {
while(true) {
Log.i("myThread", "run() method - while loop is ticking ..." + count);
// some arbitrary conditions to make stuff happen
switch(count) {
case 5:
Message messageToParent = Message.obtain();
messageToParent.what = 2;
Log.i("myThread", "About to send message to parent ...");
parentHandler.sendMessage(messageToParent);
break;
case 10:
keepGoing = false;
break;
}
if(!keepGoing) {
Log.i("myThread", "myThread is going to stop");
break;
}
count++;
sleep(500);
}
}
catch (Exception e) {
Log.e("My Log", "Thread Loop Exception - " + e);
}
Log.i("myThread", "myThread has reached the end of it's run() method");
}
public Handler getHandler() {
return myThreadHandler;
}
}
答案 0 :(得分:0)
从最初看,可能是因为您的父处理程序是私有的。将其更改为公开并尝试一次!
答案 1 :(得分:0)
我意识到当我们为处理程序编写handleMessage()
方法时,我误解了我们在做什么。
我以为我们正在为处理程序编写一个新方法,所以我将它命名为略有不同的handleMessages()
(注意复数)。
实际上我们正在做的是覆盖处理程序现有方法之一。
在我关注的示例代码中,Cristian Baita在@Override
方法之前没有使用handleMessage()
语句。这是公平的,因为@Override
只是方便您和您的编译器突出显示错误。令人尴尬的是,我认为因为@Override
不在那里,我们并没有凌驾于其中。希望这个滑动可以帮助其他人学习他们的学习曲线。