1

Handler.PostDelayed() works inconsistently for me. 1ms and 10ms delays are the same and I would also need even smaller delays in my project. Are there any other functions which I can use? Thanks!

a_local_nobody
  • 7,947
  • 5
  • 29
  • 51
Nick
  • 45
  • 8
  • why are you trying to delay ? – a_local_nobody Feb 06 '20 at 13:27
  • Well, I have this game where a ball needs to go through a gap in a moving wall. The wall moves 1px every x ms (x changes every time the ball goes through that gap, first x is 10ms). The movement of that wall, which in my case is a LinearLayout, is what's delayed – Nick Feb 06 '20 at 13:30
  • Thread.sleep(long millis, int nanos); – Amirhosein Feb 06 '20 at 13:39
  • 1
    For a game you actualy need to sync skiped frames, adding then to the current time and keep a frame rate of 60 fps, we do use a delta time over the motion instead of relying on the frame rate – Marcos Vasconcelos Feb 06 '20 at 13:42
  • I've tried with Thread.sleep() and TimeUtils.MILLISECONDS.wait(). Both need to be surrounded with try and catch and for some reason completly freeze the game. – Nick Feb 06 '20 at 13:59
  • @Nick, people are trying to answer your question of, "how can I access a more accurate timer"? But you may be missing the real point. Games, whether `View`-based or `GLSurfaceView`-based, have a max refresh rate based on the device's screen refresh rate, typically 60Hz. Trying to do any timing at intervals finer than 16.7ms is non-sensical, because changes can't show up on the screen any faster than that. This indicates you need to improve your game's architecture. IOW, you should be thinking in terms of frames, not milliseconds. – greeble31 Feb 06 '20 at 15:00
  • @greeble31 I wasn't exacly thinking about that... Thank you! – Nick Feb 06 '20 at 15:04

2 Answers2

0

You can try this:

    Timer t = new Timer();

    t.scheduleAtFixedRate(
            new TimerTask() {

                @Override
                public void run() {

                        // Your code
                        cancel(); // For exit to loop

                    }

                }

            },
            0,
            100); // Period: time in milliseconds between successive task executions.
0

You can use Kotlin coroutines for this.

Excerpt from the documentation:

import kotlinx.coroutines.*

fun main() {
    GlobalScope.launch { // launch a new coroutine in background and continue
        delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
        println("World!") // print after delay
    }
    println("Hello,") // main thread continues while coroutine is delayed
    Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}

You can cycle operations and consume significantly less resources:

fun main() = runBlocking {
    repeat(100_000) { // launch a lot of coroutines
        launch {
            delay(1000L)
            print(".")
        }
    }
}

The following article may be helpful: Kotlin Coroutines — Thread.sleep() vs delay

You can also consider CountDownTimer

Evgeny
  • 431
  • 3
  • 10
  • 1
    `CountDownTimer` is based on `sendMessageDelayed()`, which is the same thing `postDelayed()` uses... – greeble31 Feb 06 '20 at 13:47
  • My game is written in java and xml. If I'm not mistaken, this won't work (correct me if I'm wrong). – Nick Feb 06 '20 at 13:54