29

私はアンドロイドが初めてで、公式のアンドロイド Web サイトでデモ アプリケーションを読んでいました。Handlerそして、 as という名前のクラスのメソッドに出くわしましたpostDelayed(Runnable r, long milliseconds)

このメソッドが何をするのか、誰か説明してもらえますか?

4

3 に答える 3

52

ドキュメントを見ることができます。

ただし、ドキュメントを理解するには、まずいくつかの概念を理解する必要があります:メッセージ、メッセージ キュー、ハンドラー、ルーパー、およびそれらの関係

以下は、ルーパーがどのように機能するかを示しています。ルーパーがスレッド ローカル オブジェクトであり、MessageQueue との関係があることを示しています。

class Looper{
    public static final void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }

    public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next(); // might block
            if (msg != null) {
                if (msg.target == null) {
                    // No target is a magic identifier for the quit message.
                    return;
                }
                msg.target.dispatchMessage(msg);
                msg.recycle();
            }
        }
    }
}

いくつかの注意事項:

ルーパーは、すべてのスレッドが 1 つのルーパーを持つようなスレッド ローカル オブジェクトです。すべてのルーパーは、メッセージ キューに関連付けられています。ルーパーは、キューからメッセージ (「タスク」、「コマンド」、または呼び出したいもの) を継続的に取得し、そのメッセージをそのメッセージを処理するハンドラーであるターゲットにディスパッチします (たとえば、含まれている Runnable をコールバックすることによって)。メッセージ)。キューにメッセージが残っていない場合、スレッドは新しいメッセージがあるまでブロックされます。ルーパーを停止するには、その上で quit() を呼び出す必要があります (これはおそらくループをすぐに停止するのではなく、ループから定期的にチェックされるプライベート フラグを設定し、ループを停止するように通知します)。

Android フレームワークは、物事を簡素化するために Handler クラスを提供します。Handler インスタンスを作成すると、(デフォルトで) 現在のスレッドにすでにアタッチされている Looper にバインドされます。(Handler は、ThreadLocal に Looper への参照を格納した prepare() を以前に呼び出したため、どの Looper にアタッチするかを認識しています。)

ハンドラーを使用すると、post() を呼び出すだけで「メッセージをスレッドのメッセージ キューに入れる」ことができます (いわば)。Handler はすべての IdleHandler コールバックを処理し、投稿された Runnable が確実に実行されるようにします。(遅れて投稿した場合は、時間がすでに正しいかどうかも確認する場合があります。)

次のコードは、それらを使用する典型的な方法を示しています。

class LooperThread extends Thread {
  public Handler mHandler;

  public void run() {
      Looper.prepare();

      mHandler = new Handler() {
          public void handleMessage(Message msg) {
              // process incoming messages here
          }
      };

      Looper.loop();
  }

}

Handler は、Android サービスで広く使用されています。Android はアプリケーション間通信をサポートします。通常、マルチスレッドを処理する必要のないサービスを実装する場合、クライアントからの呼び出しごとにコールバックを受け取る Handler を実装します。次に、Binder オブジェクトである Messenger オブジェクト (Handler への参照) を作成し、クライアントがこのサービスをバインドするときに、このオブジェクトをクライアントに返します。したがって、クライアントはこの Messenger を使用してメッセージを (スレッド ローカル キューに入れ、Looper を介してハンドラーに送信する) このサービスに送信し、ハンドラーでそれらを処理することができます。コードサンプルが添付されています:

public class MessengerService extends Service {
    /** Command to the service to display a message */
    static final int MSG_SAY_HELLO = 1;

    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }


    final Messenger mMessenger = new Messenger(new IncomingHandler());

    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}
于 2013-01-30T10:38:34.133 に答える
6

postDelayed (Runnable r, long delayMillis)

がメッセージキューRunnable rに追加され、指定された時間が経過した後に実行されます。は、このrunnableハンドラーがアタッチされているスレッドで実行されます。

  • Runnable実行可能なコマンドを表します。

  • delayMillisは、実行されるまでの時間を表します。

基本的には、コマンド(何らかのコードかもしれません)の実行を特定の時間(delayMillis)遅らせて、指定された時間後にコマンドを実行します。

于 2013-01-30T10:31:43.507 に答える