Android Question MQTT Freezing for some seconds on app start ...

quique

Member
Licensed User
Longtime User
Hi there!

I am developing a small app that turns a light on / off on my arduino through an Android App.

I did copy the Starter code used in MQTT official examples, with the working boolean and the sub ConnectAndReconnect, etc.

Whenever I start my app, it takes about 5 - 10 seconds to get into the main code and showing my layout.

Is as it freezes on Service_create and ConnectAndReconnect subs ... there are two Sleep(5000) thrown in there which I suspect are responsible for the freeze. But I thought that the Starter code was asynchronous.

Please any explanation or hint is welcome, I am not proficient on this.

Regards,

Enrique
 

quique

Member
Licensed User
Longtime User
Hi Erel,

Yes, I am attaching it down here. In my phone, a Moto Z play, it takes about 8 seconds to reach the main activity and loading the Layout1 ...
 

Attachments

  • mqtt_erel_test.zip
    432.5 KB · Views: 210
Upvote 0

quique

Member
Licensed User
Longtime User
Erel,

An update: If i do working = false (so the ConnectAndReconnect sub does not loop into the mqtt connection try/retry) then the app starts up instantly. It seems that those Sleep(5000) are blocking the app, after all.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
@quique You should use File - Export as zip when uploading projects.

The problem is:

1. Remove this line from Service_Create:
B4X:
mqtt.Initialize("mqtt", servidor , idclient)

2. mqtt.Close tries to close the connection and this happens on the main thread. You shouldn't initialize mqtt before the loop as it will be initialized internally.
 
Upvote 0

quique

Member
Licensed User
Longtime User
@Erel and @Johan Hormaza Thank you.

At the end, since I needed the service to be kept running in the background even when the app is not in focus, I ditched the whole mqtt from the Starter service, moved it into a new service, with the:

#StartCommandReturnValue: android.app.Service.START_STICKY

and inside it I start it with the:

Service.StartForeground( 1,bgrunning)

...

Then I broke the mqtt connection process into several subs, eliminating the whole loop thing. This is the whole code, in the event that others find it useful. I got a concern about it tho: @Erel When the mqtt library looses connection with the mqtt broker, it will always call Private Sub mqtt_Disconnected ? Or the "foolproof" "reconnect" only works in loop mode, as in the previous code you guys helped me with ?


B4X:
#StartCommandReturnValue: android.app.Service.START_STICKY

Sub Process_Globals
    Public mqtt As MqttClient
    Private servidor As String = "ssl://test.mosquitto.org:8883"
    Public idcliente As String
    Public estado As String ="Initializing"
    Private username As String = ""
    Private password As String = ""
    Dim bgrunning As Notification
End Sub

Sub Service_Create
    notifystatus
    Dim r As Reflector
    idcliente= "A-" & r.GetStaticField("android.os.Build", "SERIAL") 
    connectmqtt
End Sub

Sub connectmqtt
    'If mqtt.IsInitialized Then mqtt.Close
    mqtt.Initialize("mqtt", servidor , idcliente)
    Dim mo As MqttConnectOptions
    mo.Initialize(username, password)
    estado = "Connecting ..."
    notifystatus
    mqtt.Connect2(mo)
End Sub


Sub mqtt_Connected (Success As Boolean)
    If mqtt.Connected=True Then
        mqtt.Subscribe(torreout, 0)
        estado = "Connected"
        notifystatus
    Else
        Log(LastException)
        estado = "Connection Error"
        notifystatus
        Sleep(5000)
        connectmqtt
    End If
End Sub


Private Sub mqtt_Disconnected
    estado = "Disconnected"
    notifystatus
    Sleep(5000)
    connectmqtt
End Sub


Sub notifystatus
    bgrunning.Initialize
    bgrunning.Sound = False
    bgrunning.Icon = "icon"
    bgrunning.SetInfo("MQTT CLIENT","MQTT STATUS: " & estado, Main)
    Service.StartForeground( 1,bgrunning)
End Sub
 
Upvote 0

quique

Member
Licensed User
Longtime User
@quique You should use File - Export as zip when uploading projects.

The problem is:

1. Remove this line from Service_Create:
B4X:
mqtt.Initialize("mqtt", servidor , idclient)

2. mqtt.Close tries to close the connection and this happens on the main thread. You shouldn't initialize mqtt before the loop as it will be initialized internally.

Erel, just in case you want to fix your example, FYI: https://www.b4x.com/android/forum/threads/b4x-mqtt-connect-reconnect.80815/#content
 
Upvote 0

quique

Member
Licensed User
Longtime User
Erel, I got my app working in the background for 12 hours long in my phone. I got to think it is thanks to the ...

B4X:
#StartCommandReturnValue: android.app.Service.START_STICKY

and/or the:

B4X:
Service.StartForeground( 1,bgrunning)

And also, my mqtt connection is working as expected: It connects quite fast, and when I cut network access to my device, it immediately calls Sub
mqtt_Disconnected which in turn waits 5 seconds and retries ... all the while updating the -ever present- notification of "App working in the background".

I will keep testing it, but it seems I do not have my earlier questions open any more. Again the code above seems to be working OK.

Some other pieces of code, I needed to include for the whole thing to work ok:

1) Under the Main Activity, the "sticky" service is called only at First time inside Sub Activity_create

2) When user wants to "completely close the app", I issue:

B4X:
sticky.mqtt.close
StopService(sticky)
ExitApplication

And that's it ... it seems to work. I got some weird glitches, but they are coming from the mqtt library. I.E. : If I cut network access on my phone and later I get it up again, the mqtt library reconnects OK but calls my code with the last incoming packet AGAIN (so I get an already received packet again). I have to check this and when I am sure it is not my code doing weird things, I will post a question about it.

Thanks Erel for all your work, it's incredible! I am renovating my B4A license since 2011, and I will purchase a license for B4I over the next weeks.

Enrique
 
Upvote 0
Top