Android Question Timer Tick doesn't fire

Patrick Clark

Active Member
Licensed User
Hi.

Has anybody experienced this?

I initialize a timer to tick after 2000ms and enable it but it never fires.

I sometimes get a dialog saying that the timer event cannot be found, but it is there and it is correct.

Other times it just doesn't fire at all.

I can't give any more information than that as it is pretty random.
 

Patrick Clark

Active Member
Licensed User
I don't think there is anything wrong with the code but the Log("brk Ticked") never executes

B4X:
Private Sub Class_Globals
    Public brktmr As Timer                    'check Broker responds before Timeout
    Public brkAck As Int
    Public const brkTimeout As Int = 5000    '5 second timeout
End Sub   

Private Sub startBroker
    ...
    brktmr.Initialize("brktmr", brkTimeout)
    brktmr.Enabled = True
    ...
End Sub

Private Sub brktmr_Tick
    Log("brk Ticked")
    brktmr.Enabled = False
    brkAck = -1    ' Broker not connected
End Sub
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
I don't think there is anything wrong with the code but the Log("brk Ticked") never executes
I don´t see a call to startBroker in your code. It must be called to initialize and enable the timer.
 
Upvote 0

Patrick Clark

Active Member
Licensed User
It is called
if I change that part of the code to this, I get the "About to Start Broker" in the Log

B4X:
Private Sub startBroker

    ...
    Log("About to Start Broker")
    brktmr.Initialize("brktmr", brkTimeout)
    brktmr.Enabled = True
    ...

End Sub
 
Upvote 0

Patrick Clark

Active Member
Licensed User
That is why my question was has anybody seen it before :) I didn't expect anybody to be able to help unless they had come across it.

I have other programmes where timers are working correctly and if I write a small test app they seem to work. So it must be something to do with this App.

Does having a timer in a Class make any difference?
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
You should move the declaration of the Timer from Globals to Process_Globals.
From the help:
Timers should be declared in Sub Process_Globals. Otherwise you may get multiple timers running when the activity is recreated.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Timers should be declared in Sub Process_Globals. Otherwise you may get multiple timers running when the activity is recreated.
@Patrick Clark is using his timer in a class, so the declaration in Class_Globals should be fine. The question is, where is this class initiated? How are you testing this? For example, if you are initiating this class in an Activity and then you test it but you close the activity, the timer event sub will not be called, since all Activity processing will stop. You may or may not see something in the log output about an event not being able to be processed. Again, @DonManfred is correct: We are not getting enough information from you on how this is used, how this is tested and what logs you are getting. We would need a complete log from "About to start broker" to at least several seconds after you expected the timer to fire. Right now you are giving us pretty much nothing...
 
Upvote 0

Patrick Clark

Active Member
Licensed User
You should move the declaration of the Timer from Globals to Process_Globals.
From the help:
Timers should be declared in Sub Process_Globals. Otherwise you may get multiple timers running when the activity is recreated.
@OliverA , @DonManfred Thanks both for you input. At @klaus suggestion, I have moved the declaration to Sub Process_Globals and it works fine.

With regard to where I was initialising the Class. It is in (Main) Activity_Create. I then load a layout which has a number of buttons. One of which calls the startBroker in the class with msg.startBroker, so the Activity is still active.

B4X:
Sub Globals
    Private msg As MSGe
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("mqtttestclient")
    msg.Initialize("192.168.1.106", 51042, "", "")
End Sub

Sub BtnStart_Click
    Wait For (msg.startBroker) complete (Success As Boolean)
    If Success Then
        lblStatus.Text = "Running"
    Else
        lblStatus.Text = "Couldn't Start Service"
    End If
End Sub

Anyway, Thanks All. My problem is solved although i don't understand why it wouldn't work when declared in the class.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
@Patrick Clark is using his timer in a class, so the declaration in Class_Globals should be fine.
I missed that one.
You are right, it should work also when the Timer is declared in the Class.
And as you say it depends how the class is declared and initialized.
 
Upvote 0

Patrick Clark

Active Member
Licensed User
Ok I think I know what's causing it.

What I am doing is setting a acknowledge flag that is set to successful by a client.connect event but if that doesn't happen before the timer ticks then the Tick code set the acknowledge flag to failed

The code I am using is this and I think the problem is a conflict with the sleep and timer. If I put Log("Still Waiting" ) after the sleep it works!

Is there a better way of doing this. I don't want to continue if the connection isn't successful.

B4X:
'in the start broker sub
'
Acknowledged = 0
brktmr.Initialize("brktmr", 2000)
brktmr.Enabled = True

Do While Acknowledged = 0
    Sleep(50)
Loop

'at this point Acknowledged should be:
'    1 (from the client.connected event) or
'    -1 from the brktmr_Tick event

'the Timer tick
Sub brktmr_Tick
    brktmr.Enabled = False
    Acknowledged = -1
End Sub
 
Upvote 0
Top