Android Question Wait For not waiting?

Computersmith64

Well-Known Member
Licensed User
Longtime User
Per the code below, I am using a Wait For (per Erel's tutorial here) to wait until my Google Maps Fragment is ready, then moving to my current position. The checkForNewMessage sub is called from Activity_Resume.

The problem is that the Wait For in checkForNewMessage doesn't wait for the mapGMap_Ready callback to be fired, so the app crashes on the first line of gotoMyLocation because at that point gmap is not initialized. If I comment out the Wait For statement & uncomment the Do While loop under it, it works fine - which seems to confirm that the Wait For isn't working.

Is this a bug with Wait For, or am I missing something?

(gmap is a GoogleMap object declared in Globals & mapGMap is a MapFragment added to the layout in the designer)

B4X:
Private Sub checkForNewMessage
 
    If Not(gmap.IsInitialized) Then
        Wait For mapGMap_Ready
    End If
    Log("Map Fragment Ready")
 
'    Do While Not(gmap.IsInitialized)
'        Log("NOT INITIALIZED")
'        Sleep(0)
'    Loop
 
    Private newIntent As Intent = Activity.GetStartingIntent
    If newIntent.HasExtra("Notification_Tag") Then
        If newIntent.GetExtra("Notification_Tag") = "notification-start" Then
            updateMap(FirebaseMessaging.notificationMsg)
        End If
    Else
        gotoMyLocation
    End If
End Sub

Private Sub mapGMap_Ready
    Log("GMAP READY")
    gmap = mapGMap.GetMap
 
    markerMap.Initialize
    gmap.MyLocationEnabled = True
    snippetClickListener.Initialize("InfoWindow")
    gmapExtras.SetOnInfoWindowClickListener(gmap, snippetClickListener)
    loadLocationRecords
 
    Dim jo As JavaObject = gmap
    Dim event As Object = jo.CreateEventFromUI("com.google.android.gms.maps.GoogleMap.OnInfoWindowLongClickListener", _
       "InfoWindowLongClick", Null)
    jo.RunMethod("setOnInfoWindowLongClickListener", Array(event))

End Sub

Private Sub gotoMyLocation
 
    Do While Not(gmap.MyLocation.IsInitialized)
        Log("My Location not initialized")
        Sleep(0)
    Loop
    pos.Initialize(gmap.MyLocation.Latitude, gmap.MyLocation.Longitude, markerZoom)
    gmap.AnimateCamera(pos)
End Sub

- Colin.
 
Last edited:

eps

Expert
Licensed User
Longtime User
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Because MapFragment1_Ready isn't called every time the activity resumes. Plus this doesn't address the issue of the Wait For not waiting.

- Colin.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Your code is wrong. Sub mapGMap_Ready will not be called as the Wait For line "steals" the event.

Waiting for the map to be ready:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("1")
   Wait For MapFragment1_Ready
   gmap = MapFragment1.GetMap
   If gmap.IsInitialized Then
     gmap.AddMarker(30, 30, "Testing 1, 2, 3")
   End If
End Sub
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
OK - so the thing to remember with Wait For is that it effectively consumes the callback.

- Colin.
 
Upvote 0

Alexander Stolte

Expert
Licensed User
Longtime User
I still have the same problems after that, my code:

B4X:
Sub Globals
Private mf_main As MapFragment
    Private gmap As GoogleMap
End Sub

Sub Activity_Create(FirstTime As Boolean)
dim lat as float
dim lon as float

Wait For mf_main_Ready
    gmap = mf_main.GetMap
    If gmap.IsInitialized Then
    lat = gmap.MyLocation.Latitude
    lon = gmap.MyLocation.Longitude
    gc_geo.GetFromLocation(gmap.MyLocation.Latitude, gmap.MyLocation.Longitude, 5, Null)
    End If
End Sub

i'm waiting for the map, but it comes this error:

B4X:
Error occurred on line: 279 (Main2)
java.lang.RuntimeException: Object should first be initialized (LatLng).
    at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:50)
    at anywheresoftware.b4a.objects.MapFragmentWrapper$LatLngWrapper.getLatitude(MapFragmentWrapper.java:391)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:710)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:339)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:166)
    at anywheresoftware.b4a.shell.DebugResumableSub$RemoteResumableSub.resume(DebugResumableSub.java:19)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:240)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:132)
    at anywheresoftware.b4a.BA$1.run(BA.java:325)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6692)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

the map is added via designer. A workaround is to set a Sleep(1000) but sometimes, the 1 second pause does not and it comes the same error.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User

I think the reason you are getting that crash is because gmap.MyLocation isn't initialized yet. To get around this I use:

B4X:
Do While Not(gmap.MyLocation.IsInitialized)
    Sleep(0)
Loop
'Do whatever with MyLocation as it's now initialized

It's pretty ugly, but there is no callback (that I can find) you can use with Wait For, so this is my workaround...

- Colin.
 
Upvote 0

Alexander Stolte

Expert
Licensed User
Longtime User
Can you post your code with the loop in it & also point out exactly which line the error is on?

B4X:
Sub mf_main_Ready
    
    Do While Not(gmap.MyLocation.IsInitialized)
       
        Sleep(0)
    Loop

End Sub

and exactly comes the error in this line:

B4X:
lat = gmap.MyLocation.Latitude
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
If Sub mf_main_Ready is the callback for the MapFragment object, it will never be called because you are "stealing" it with your Wait For. You need to put the loop like this:
B4X:
Sub Globals
    Private mf_main As MapFragment
    Private gmap As GoogleMap
End Sub

Sub Activity_Create(FirstTime As Boolean)
    dim lat as float
    dim lon as float
   
    WaitFor mf_main_Ready
    gmap = mf_main.GetMap
    If gmap.IsInitialized Then
         Do While Not(gmap.MyLocation.IsInitialized)
             Sleep(0)
         Loop
         lat = gmap.MyLocation.Latitude     'This line & the next are redundant, because you're not using lat & lon anywhere in this sub
         lon = gmap.MyLocation.Longitude
         gc_geo.GetFromLocation(gmap.MyLocation.Latitude, gmap.MyLocation.Longitude, 5, Null)
    End If
End Sub

- Colin.
 
Upvote 0