ルーパーを追加する独自のThreadFactoryでExecutor[固定スレッドプール]を使用しています。
Handler HANDLER = new Handler();
Executor THREADS = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ThreadFactory() {
@Override public Thread newThread(Runnable runnable) {
return new MyThread(new Runnable() {
@Override public void run() {
Looper.prepare();
runnable.run();
}
});
}
});
private static class MyHandler extends Handler {
public boolean fail;
public void handleMessage(Message msg) {
switch(msg.what) {
case 1:
this.fail = msg.arg1 == 1;
Looper.myLooper().quit();
break;
}
}
}
}
ネットワーク要求を行うスレッドを実行していますが、ネットワークに障害が発生した場合、ダイアログメッセージをユーザーに表示したいと思います。このプロセスは、UIスレッドでリクエストを作成して表示する必要があるため、かなり複雑です。ネットワークスレッドにループを追加し、UIスレッドからメッセージが送信されるのを待つだけで、ダイアログに対するユーザーの応答を待つことができます。これにより、ネットワーク要求をwhile(tryAgain)スレッドにカプセル化できます。Looper.loop()メソッドが2回目に呼び出され(2番目のネットワークエラーダイアログが表示された後)、ダイアログによって(UIスレッドで)メッセージがネットワークスレッドのハンドラーに送信される場合を除いて、すべてが正常に機能します。
THREADS.execute(new Runnable() {
private MyHandler myHandler = new MyHandler();
@Override public void run() {
boolean tryAgain = true;
while(tryAgain) {
try {
switch(request) {
[Handle network requests]
}
tryAgain = false;
} catch(IOException e) {
// The network is unavailable. Ask the user if we should try again.
e.printStackTrace();
} finally {
if(tryAgain) {
HANDLER.post(new Runnable() { // The UI thread
@Override public void run() {
theAlertDialog.show();
}
});
// Wait for the results from the dialog which lives in the UI thread.
Looper.loop();
// At this point the dialog has informed us of our answer.
tryAgain = !myHandler.fail;
}
}
}
}
});
AlertDialogインスタンスには、OnClickListenerがあります。
DialogInterface.OnClickListener myOnclickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Message msg = myHandler.obtainMessage(1);
msg.setTarget(this.handler);
msg.sendToTarget();
}
}
スレッドがまだアクティブでhandler.getLooper().getThread().isAlive()
あり、常にtrueを返すことを確認しましたが、それでも「デッドスレッドのハンドラーにメッセージを送信する」ことができます。メッセージ/ハンドラーがスレッドが停止しているとどのように判断したのですか?.isAlive()メソッドに依存するべきではありませんか?結局、私はスレッド管理ビルドをAndroidOSに複製することを避けようとしています:-)