2

私はHandlerThreadAndroidで利用しようとしていますが、UIスレッドが応答しなくなる状況か、奇妙な状況に陥っていますIllegalStateException。私の問題の最小限の例を紹介したいと思います。

DataManager作成時にワーカースレッドをインスタンス化するクラスがあります。

public class DataManager
{
    private final HandlerThread loaderThread = new HandlerThread( "Worker" );
    private final Producer loader;

このクラスの中に、私は自分のHandler定義を持っています:

    private static class Producer extends Handler
    {
        public Producer( Looper looper )
        {
            super( looper );
        }

        @Override
        public void handleMessage( Message msg )
        {
            msg.recycle();
        }
    }

myのコンストラクターはDataManager、ワーカースレッドを実行し、ハンドラーをスレッドのルーパーに関連付けます。

    public DataManager()
    {
        loaderThread.start();
        this.loader = new Producer( loaderThread.getLooper() );
    }

破棄される前にDataManager、スレッドを停止し、終了するのを待ちます。実際、私のDataManagerインスタンスは常に生きているので、この部分は私の問題とは関係がないと思います。

    @Override
    protected void finalize() throws Throwable
    {
        loaderThread.quit();
        loaderThread.join();

        super.finalize();
    }

最後にdoSomething、ワーカースレッドにメッセージを投稿するだけのメソッドがあります。

    public void doSomething()
    {
        Message msg = Message.obtain();
        loader.sendMessage( msg );
    }

DataManagerこれで、UIスレッドのカスタムビューの内部からインスタンス化しています。ビューがそれを使用してそれ自体をペイントしようとしているとき、をonDraw呼び出しdoSomethingますDataManager。それ以降の動作は、AsyncTaskが現在バックグラウンドで実行されているかどうかによって異なります。

  • それが実行されている場合、UIスレッドはこの瞬間から応答しなくなります。
  • それ以外の場合は、UIスレッドのIllegalStateExceptionサブルーチン内からスローされ、次のようになります。Looper.loop

    IllegalStateException:指定されたメッセージキュー同期バリアトークンが投稿されていないか、すでに削除されています。

Googleは、このメッセージに対してまったく結果を出しません。私はドキュメントを読んで同様の問題を数時間探してきましたが、何が間違っているのかまだわかりません。何か案は?

4

1 に答える 1

6

とった。明らかに、メッセージのリサイクルに関する状況はのとおりです。

あなたがそれをハンドラーに送るならば、ハンドラー/ルーパーはあなたのためにそれをリサイクルします。

したがって、内でメッセージをリサイクルしてはなりませんhandleMessage

于 2013-02-03T17:43:57.057 に答える