以下のテスト アプリは、Cristian Baita によるこのスレッド チュートリアルに大まかに基づいています。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() メソッドでスレッドを作成するときに、handler を渡します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);
メッセージはmainHandler
、MainActivity で定義されたものによって受信されます。
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 が "Message Received" または "Handled message..." をログに記録しないことがわかります。そのため、メッセージは宛先に届きません。
メインアクティビティ:
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;
}
}