Android Question Run Timer and Tick event in non-GUI thread

swabygw

Active Member
Licensed User
Longtime User
I have a Metronome application which users a Timer. I've gotten the Timer to work very well, but I've noticed that it is susceptible to getting off the beat once in a while (when something else runs on the phone, I think). I think this can be solved by running the Timer in its own thread (a non-GUI thread). But I'm trying to figure out how to code this. This what I'm thinking:

Sub Process_Globals
Dim Thread1 As Thread
Dim Timer1 As Timer​
End Sub

Sub Activity_Create(FirstTime As Boolean)
Thread1.Initialise("Thread1")
Thread1.Start(Null,"ThreadStuff", Null) (1) Can I call it like this (I got some strange errors about missing parameters when I tried this)?
End Sub

Sub ThreadStuff
Timer1.Initialize("Timer1", 1000)
Timer1.Enabled = True​
End Sub

Sub countInTimer_Tick()
(2) Can I write a Log(DateTime.Now) here (I wasn't sure if the Log is available to the thread...it wouldn't write to the Log when I tried it in a GUI thread)?
End Sub

My questions are above in red...thanks!
 

swabygw

Active Member
Licensed User
Longtime User
I wrote the application, originally, without Threading, and got it to have very good accuracy, actually. I used one Timer, running at a high frequency (every 10 milliseconds), and checked the DateTime.Now to determine when the threshold has been reached/passed. This works pretty good...about +/- 15 milliseconds off, which is acceptable, I think. However, every once in a while...I'd say around every half a minute to a minute, something else runs on the phone which makes the timing be off by about 350 milliseconds - this is the thing that I'd like to evade.
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
I tried it two ways in Release Mode: a) without Threading, and b) with RunOnGuiThread. Both provided fairly accurate results. But both provided occasional blips in the timing (not sure exactly by how much because logging wasn't available...but it can be slightly heard every once in a while).
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Note that you can monitor the logs if you connect to device in USB debug mode.

I've tried it with this code:
B4X:
Sub Process_Globals
   Private timer1 As Timer   
   Private prev As Long
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
     timer1.Initialize("Timer1", 1000)
     timer1.Enabled = True
   End If
End Sub

Sub Timer1_Tick
   Log(DateTime.Now - prev)
   prev = DateTime.Now
   Activity.Title = DateTime.Now - prev
End Sub
I ran it for several minutes.
The values were between 1000 to 1002. Sounds reasonable to me. You can make it more accurate by setting the timer to 990 and hold the main thread until the exact time.

My guess is that the problem is somewhere else. How are you generating the sounds?
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
Actually, my program was getting something similar. But, about every 10th or 12th second, the number jumped to about 1020 in mine...but not in yours. You've drawn my attention to some other things going on in the program, though.

First, I've been using the B4A Bridge wirelessly, and I noticed that when I made a change to the text coming out in the Log, for example, it reflected that change. But, sometimes, if I did an Undo and saved it and ran the program again, the text in the Log didn't change. So, now I'm suspicious that my program is running a cached version sometimes and not always the latest/greatest.

Second, I've noticed that if I comment out a call from, for example, Sub A to Sub B, which leaves a Sub B uncalled, this increases the time in the Timer difference to about 1030. If I uncomment the call and just comment out the code with the Sub B, the time drops back down to about 1005.

These two observations are leading me to conclude that the contents of the entire program is being reassessed constantly and this reassessment has an impact on the performance. I no longer think that a separate Thread is necessary but, rather, there must be some inefficiency in the code (for example, instead of newly declaring a variable in a loop, declare it once outside of the loop and set it each time within the loop). But, is there a way to enforce that each time the program is run on the phone via the B4A Bridge, the program has been fully replaced by the latest version of the code?
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
Sorry for the long post...to summarize: hot-swapped code causes the time to jump from being off +/- 5 to, for example, +/- 30. If I undo the change and hot-swap back, the time difference drops back down. Hot-swapping has been causing some hit to performance. When a minor code change is made, how can a full reinstall be forced rather than just a hot-swap?

(I've found that switching the name of some variable in the Globals section forces a full reinstall. After doing so, here are my timing results. Within a hundred seconds, all were super-close to right on target except these:
#17, Time: 13
#48, Time: 14
#53, Time: 13
#66, Time: 15
#76, Time: 17
#94, Time: 12
#102, Time: 14
)
 
Last edited:
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
Solved. Yes, I was using Release Mode (answered above in Post #5). The foul-up was when I tried the USB debugging to see the logging output (and, yes, I had the USB debugging checked in the Android Settings). On the Sony xPeria Z1 (not sure if this is on other devices), when you plug in a USB cable connecting it to the PC, it provides a popup on the phone with, about, six options on how to treat the connection (e.g., Mass Transfer, Install Applications, Media Transfer, etc.). I had selected Install Applications once. Another time, I had chosen Mass Transfer. The solution was to, actually, not make any selection...let the popup box stay up and the phone will stay in debugging mode - if any choice is made, it exits debugging mode.

After leaving the popup up, my phone appeared to stay in debugging mode and, while, again, running in Release Mode, I got the same numbers you got +/-2, with no large differences. Thanks for the help.
 
Upvote 0
Top