0

簡単な質問があります。以前に終了したスレッドの Looper を再起動 (re-loop()) することはできますか。たとえば、次のようにスレッドを設計しました。

public class ProvaThread extends Thread implements Runnable{

        public void run(){

            Looper.prepare();
            Handler handler = new Handler(){
                Log.d(TAG, "handle message..");
                @Override
                public void handleMessage(Message msg){

                    getLooper().quit();
                }
            };

            Looper.loop(); //loop 1

            Log.d(TAG, "thread continue (1)...");

            Looper.loop(); //loop 2

            Log.d(TAG, "thread continue (2)...");

        }
    }

私はこのコードを試しましたが、2回目にハンドラーにメッセージを投稿しようとするとRuntimeExceptionデッドスレッドのハンドラーにメッセージを送信するhandleMessage())を取得します(2回目以降は呼び出されませんloop())。が呼び出されたときgetLooper().quit()に呼び出すloop()ことはできますが、新しいメッセージを処理することはできません。それ以外の場合は例外がスローされます)。それが正しいか?

これを行うには、wait()/notify() を使用する必要がありますか??

4

2 に答える 2

3

最初に、サンプル コードが機能しない理由を説明しましょう。Looper は MessageQueue を 1 つだけ処理します。この MessageQueue は Looper.prepare() を呼び出すと作成され、メッセージは Looper.loop() を呼び出すと処理されます。Looper.quit() を呼び出すと、次の 2 つのことが起こります。

  1. Looper への MessageQueue は、着信メッセージを処理しない最終的な端末状態になります。RuntimeException がスローされます。
  2. Looper がメッセージを取得しようとすると、メッセージとして「null」のみが返されます。

したがって、(1) が RuntimeException の理由であり、(2) Looper.loop() を使用してメッセージの取得を試行および再起動できますが、MessageQueue から返されるのは「null」オブジェクトのみです。

次に、UI とワーカー スレッド間の継続的な通信を解決するためのより良いアプローチを提案します。

  1. mUiHandler と呼ばれる UI スレッドのハンドラーを作成します。
  2. HandlerThread などのワーカー スレッドを作成し、mWorkerHandler と呼ばれる Handler を公開します。

ここで、2 つのハンドラーがメッセージをやり取りして通信できるようにします。バックグラウンド タスクのためにメッセージを mWorkerHandler に投稿し、ダイアログが表示または削除されるたびに、ワーカー スレッドがメッセージを mUiHandler に投稿できるようにします。

于 2013-01-26T22:06:06.650 に答える
0

この短い記事http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/を読む必要があると思います。Looperの仕組みと使用方法について説明します。

于 2013-01-24T22:22:39.577 に答える