Android Question Sleep for Milliseconds

brianoh

Member
Licensed User
I'm just starting to try B4A and need to implement a sleep for eg. 1000 milliseconds. I looked at Timer, but it seems unsuitable for what I want. What I want is to simply have a call to sleep amongst other code. In Java one would just do "Thread.sleep(1000)" and it would probably be within a "Try" block.

I cannot find anything equivalent in B4A, and as I said the Timer does not appear to be appropriate for what I want. I would prefer to use standard B4A and the only way I could see to do that was the following:

B4X:
Sub fn_SleepTill(lG_SleepEndMs As Long)
   Do While (DateTime.Now < lG_SleepEndMs)
   Loop
End Sub

That to me does not seem to be a good solution because it uses the CPU.

While it's easy to just put some inline Java code to do the "Thread.sleep()" I would prefer to use a B4A solution if there is one.
 

DonManfred

Expert
Licensed User
Upvote 0

brianoh

Member
Licensed User
It is not a good idea to hold the mainthread!

Use https://www.b4x.com/android/forum/threads/callsubplus-callsub-with-explicit-delay.60877/ to start a sub with a specific delay and dont block the mainthread.

I don't see that as a problem in this instance because I don't want the user to do anything.

All I want is for nothing to happen for eg. 1000 ms. In Java that would be fairly common where the current thread has nothing to do, so in order to come back later and let another thread process, just sleep for a while.

This case is different, because I want nothing to happen in order to simulate the processor doing something on the main thread. Therefore, there is nothing that the user can do for that second.

As I said, "Thread.sleep()" will do the job fine, but I just want to know if there is a B4A way of doing this in a similar way to the way "Thread.sleep()" does it and not use CPU. As I said, I don't think that "Timer" is suitable for this from what I saw.
 
Upvote 0

brianoh

Member
Licensed User
As far as I can determine, the following appears to be the best way to handle this. While I only want it to sleep for 1 second, I tried with 10 seconds and the OS didn't seem to mind.

B4X:
Sub fn_SleepNative(iN_SleepMs As Int)
   DoEvents
   g_jV_NativeMe.runMethod("fn_Sleep", Array(iN_SleepMs))
End Sub

#If JAVA
   public void fn_Sleep(int iN_SleepMs) {
     try {
       Thread.sleep(iN_SleepMs);
     } catch(InterruptedException ex) {
       Thread.currentThread().interrupt();
     }
   }
#End IF
 
Upvote 0

brianoh

Member
Licensed User
I did try to achieve this by creating a separate thread (in Java) to do the sleep(), however that did not achieve what I wanted because the UI thread obviously did not pause. What I want to achieve is to simulate the CPU thinking (while making a move). If I don't sleep, the game is over without showing the moves because obviously the CPU is too fast to show a delay. The sleep is 1000ms and it appears to work OK in the main thread in the numerous times I have tested it. I do realize that in general this should not be done, however in this case the user cannot do anything in any case because I don't want the user to do anything and I also want to delay the CPU doing anything.
 
Upvote 0

brianoh

Member
Licensed User
It is very simple to implement what you want with CallSubPlus.

I did implement the CallSubPlus, however it did not produce the desired result. The reason for this is as far as I can tell is that the main code does not wait for the code executed by the CallSubPlus to complete, but the Main code relies on the code executed by the CallSubPlus to complete. To illustrate that, if there were a Global Sub integer variable that was to be incremented by the code executed by the CallSubPlus until that variable reached (say) 9, then the Main Thread Code would always see that as zero (until all 9 CallSubsPlus had been executed), because the code required to be executed by the CallSubPlus is delayed by 1 second for each iteration. Therefore, the Main code would instead of being executed just 9 times, would (and is) executed a huge number of times. In fact, because the code is more complex that just incrementing an integer, the program never terminates. While this could be solved by having a counter and waiting for that counter to be incremented (1 to 9 times), that is effectively the same as looping for 1000 ms for each iteration which is what I want to avoid because it is not an elegant solution.

While I am quite happy to have the program sleep for 1000 ms, and testing has not shown any adverse results from that, I do not want to do that if the advice from yourselves is that it is problematic under some circumstances to do that. To put it in some context, this is a game of OandX where one option is for the computer to play against itself. The purpose of the sleep is to simulate "thinking" by the computer so that the moves can be seen. Otherwise the game is over as soon as it starts and it does not achieve what I want, which is to see each move after a 1 second delay.
 
Upvote 0

xpectmore

Member
Licensed User
I AM WONDERING IF this delay (not a timer) cam be set from 1 to 200 milisecconds .this can help cctv examples :

B4X:
camEx.SetPictureSize(320, 240)
sleep(10) 'that new java sub 10 milisecconds delay
camEx.CommitParameters

'will serve here to my fixes
'https://www.b4x.com/android/forum/threads/cctv-cool-php-fixes.76534/
 
Upvote 0
Top