0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

android.os.HandlerのpostとpostDelayedを使った際のQueueに積まれる順番について

Posted at

AndroidでHandlerのpost(Runnable r)を複数回コールした場合は、postした順にQueueに積まれて、実行されます。post(Runnable r)postDelayed(Runnable r, long delayMillis)を使った場合にどうQueueに積まれるか調べてみました。

ソースコードを見ると、postとpostDelayedの内部では共にsendMessageDelayed(Message msg, long delayMillis)が呼ばれていました。

Handler.java
    public final boolean post(@NonNull Runnable r) {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

    public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
        return sendMessageDelayed(getPostMessage(r), delayMillis);
    }

sendMessageDelayedの中ではsendMessageAtTime(Message msg, long uptimeMillis)が呼ばれており、引数のuptimeMillisにはSystemClock.uptimeMillis() + delayMillisが設定されています。

Handler.java
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

つまり、postDelayed(Runnable r, long delayMillis)はdelayMillis ミリ秒後にpost(Runnable r)をするのと同じことになります。
例えば、下記のコードを実行すると、

Sample.kt
        val handler = Handler()

        handler.postDelayed( Runnable { Log.d(TAG, "Runnable 1") }, 100)
        Log.d(TAG, "1 postDelayed")

        handler.post( Runnable {
            Log.d(TAG, "Runnable 2-1")
            Thread.sleep(100)
            Log.d(TAG, "Runnable 2-2")
        })
        Log.d(TAG, "2 post")

        handler.post( Runnable {
            Log.d(TAG, "Runnable 3-1")
            Thread.sleep(200)
            Log.d(TAG, "Runnable 3-2")
        })
        Log.d(TAG, "3 post")

ログは下記のようになります。

2020-02-08 20:08:07.385 22994-22994/Sample: 1 postDelayed
2020-02-08 20:08:07.385 22994-22994/Sample: 2 post
2020-02-08 20:08:07.385 22994-22994/Sample: 3 post
2020-02-08 20:08:07.490 22994-22994/Sample: Runnable 2-1
2020-02-08 20:08:07.591 22994-22994/Sample: Runnable 2-2
2020-02-08 20:08:07.592 22994-22994/Sample: Runnable 3-1
2020-02-08 20:08:07.793 22994-22994/Sample: Runnable 3-2
2020-02-08 20:08:07.950 22994-22994/Sample: Runnable 1

Runnable 1Runnable 3の後に実行されます。
また、postDelayedはdelayMillisを100msにしていますが、実際に実行されるのは565ms後です。
Runnable 1が、Runnable 3の前または、100ms後に実行されることを想定していると、思わぬ不具合を生むことになるので注意が必要です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?