Android Question when do apps not sequentially execute instructions

Discussion in 'Android Questions' started by jamesnz, May 31, 2019.

  1. jamesnz

    jamesnz Active Member Licensed User

    Hi,
    It seems when I have a function that calls another function that makes a call to a webservice my app does not wait for the completion of this job, instead it moves to subsequent lines of code in the calling function and executes them while the webapi is yet to respond. My debugging didn't catch this because it had plenty of time.

    Does this just occur with web jobs ? If I called another function that performed a large loop would the calling function wait, till now I assumed everything was done line by line and the jobdone sub would have to finish before subsequent lines of code were executed

    This app worked differently a few years ago, perhaps because it used a built in geocoder

    Code:
    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'These variables can be accessed from all modules.
    'Dim Geocoder1 As Geocoder
    Dim VR As VoiceRecognition
    Dim TTS1 As TTS
    End Sub

    Sub Globals
        
    'These global variables will be redeclared each time the activity is created.
        'These variables can only be accessed from this module.

    Dim RadioButtonFastest As RadioButton
    Dim RadioButtonShortest As RadioButton
    Dim EditTextCurrentAddr As EditText
    Dim EditTextDestinationAddr As EditText
    Dim ButtonGetDirections As Button

    Dim Destination As geocodedLocation
    Dim Origin As geocodedLocation
    Dim Buttonsentvoice As String = "none"
    Dim Mode As String = "shortest"
    Dim key As String ="*******************" ' mapquest
    Dim OpenRouteAPIKey As String = "******************"
    Dim parser As JSONParser

       
        
    Dim ButtonVoiceCurrentAddr As Button
        
    Dim ButtonVoiceDestAddr As Button
        
    Private ButtonDebug As Button
       
        
    Dim leavereason As String
       
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    'load the layout file created with the visual designer.
        If FirstTime Then
        
    'initialise voice recog and tts
        VR.Initialize("VR")
            TTS1.Initialize(
    "TTS1")
           
        
    End If
       
        
    'always Load screen
        Activity.LoadLayout("2GetDirections")
    'check if VR is supported
    If VR.IsSupported Then
            
    'ToastMessageShow("Voice recognition is supported.", False)
        Else
            
    ToastMessageShow("Voice recognition is not supported."True)
        
    End If
    VR.Prompt = 
    "Number / Street / City/ Country"
    Destination.Initialize
    Origin.Initialize
    Log("end of activity create")
    End Sub

    Sub Activity_Resume

    'If leavereason = "voice" Or leavereason ="geocode" Then
    ''do nothing
    '    Else
    '        Log ("running from resume")
    '        Findcurrentaddressfromlatlng
    '
    'End If
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
    ' save stuff here
    'leavereason = "sleep"
    End Sub



    Sub ButtonGetDirections_Click
        
    Log("get directions click event")
        
    If Origin.Latitude = 0 Then
             getORIGINlatlng
        
    End If
       
    ButtonGetDirections.text = EditTextCurrentAddr.Text & 
    " " & EditTextDestinationAddr .Text

    getdestlatlng

    makestringfordirections (Origin , Destination )  
    '<== EXECUTES THIS BEFORE gestdestlatlng HAS A RESULT

    End Sub

    Sub LatLngFromAddress( address As String,purpose As String)
       
        
    ' SENDS AN ADDRESS STRING FOR GEOCODING - returns a lat lng
        Dim job1 As HttpJob
        job1.Initialize(
    "geocodeaddresstolatlng",Me)
        job1.Tag=purpose
       
       
        job1.Download2(
    "https://api.openrouteservice.org/geocode/search",     Array As String("api_key", OpenRouteAPIKey, "text"address))
        
    Log(job1)
    End Sub


    Sub Findcurrentaddressfromlatlng
        
    'if we have gps we use the lat/lng to find the address string and display it to the user
        'run by resume and create
        If Main.LastLatitude <> 0 Then
        AddressfromLatLng(Main.LastLatitude, Main.LastLongitude,
    "origin")
        EditTextCurrentAddr.Text=
    ""
        EditTextCurrentAddr.Text = Origin.label  
        
    Else
            
    Log"GPS is zero")
            EditTextCurrentAddr.RequestFocus
        
    End If
       
       
    End Sub

    Sub getdestlatlng
    LatLngFromAddress(EditTextDestinationAddr .Text,
    "destination")
    End Sub

    Sub getORIGINlatlng
    If EditTextCurrentAddr.Text.Length>3 Then

       
        LocationName2=EditTextCurrentAddr .Text
        LatLngFromAddress(LocationName2,
    "origin")
        
    Else
        
    ToastMessageShow"in the top box. tell us where you are"True)
      
    End If
       
    End Sub




    #End Region
    #Region geocoding

    #region HttpStuff
    'HTTP JOB

    Sub AddressfromLatLng( latitude As Float , longitude As Float, purpose As String)
    ' SENDS LAT/LNG pair for REVERSE GEOCODING - returns an address string
        'leavereason="geocode"
        Dim job1 As HttpJob
        job1.Initialize(
    "ORSCoordinatesToAddress",Me)
        job1.Tag = purpose
        job1.Download(
    "https://api.openrouteservice.org/geocode/reverse?api_key=*********************************&point.lon="& longitude &"&point.lat="& latitude &"boundary.circle.radius=.1&size=2&sources=openstreetmap")
    End Sub

    Sub  JobDone (job As HttpJob)

    Log("tag"&job.Tag)

        
    If job.Success = True Then
       
            
    Log(job.GetString)
                
    If job.Tag ="origin" Or job.Tag="destination" Then
                    
    Dim jp As JSONParser
                    jp.Initialize(job.GetString)
                    
    Dim m As Map = jp.NextObject
           
                    
    Dim results As List = m.Get("features")
                    
    Dim bb As List = m.Get("bbox")
                    
    If results.Size > 0 Then
                        
    Dim first As Map = results.Get(0)
                        
    Dim geometry As Map = first.Get("geometry")
                        
    Dim properties As Map = first.Get("properties")
                       
                        
    'Log("this is the property map"& properties)
                       
                        
    Dim coordinates As List = geometry.Get("coordinates")
                   
                        
    If job.Tag="origin" Then
                            Origin.latitude= coordinates.Get(
    1)
                            Origin.Longitude =coordinates.Get(
    0)
                            Origin.gid=properties.Get(
    "id")
                            Origin.id=properties.Get(
    "gid")
                            Origin.layer=properties.Get(
    "layer")
                            Origin.source=properties.Get(
    "source")
                            Origin.source_id=properties.Get(
    "source_id")
                            Origin.name=properties.Get(
    "name")
                            Origin.housenumber=properties.Get(
    "housenumber")
                            Origin.street=properties.Get(
    "street")
                            Origin.confidence=properties.Get(
    "confidence")
                            
    If properties.ContainsKey("distance"Then
                            Origin.distance=properties.Get(
    "distance")
                            
    End If
                            Origin.accuracy=properties.Get(
    "accuracy")
                            Origin.country=properties.Get(
    "country")
                            Origin.country_gid=properties.Get(
    "country_gid")
                            Origin.country_a=properties.Get(
    "country_a")
                            Origin.region=properties.Get(
    "region")
                            Origin.region_gid=properties.Get(
    "region_gid")
                            Origin.region_a=properties.Get(
    "region_a")
                            Origin.county=properties.Get(
    "county")
                            Origin.county_gid=properties.Get(
    "county_gid")
                            Origin.county_a=properties.Get(
    "county_a")
                            Origin.locality=properties.Get(
    "locality")
                            Origin.locality_gid=properties.Get(
    "locality_gid")
                            Origin.continent=properties.Get(
    "continent")
                            Origin.continent_gid=properties.Get(
    "continent_gid")
                            Origin.label=properties.Get(
    "label")
                            Origin.BoundingBox=bb
                            
    Log("Origin SUCCESFULLY SET = " & Origin)
                           
                        
    else if job.Tag ="destination" Then
                       
                                Destination.latitude= coordinates.Get(
    1)
                                Destination.Longitude =coordinates.Get(
    0)
                                 Destination.gid=properties.Get(
    "id")
                                Destination.id=properties.Get(
    "gid")
                                Destination.layer=properties.Get(
    "layer")
                                Destination.source=properties.Get(
    "source")
                                Destination.source_id=properties.Get(
    "source_id")
                                Destination.name=properties.Get(
    "name")
                                Destination.housenumber=properties.Get(
    "housenumber")
                                Destination.street=properties.Get(
    "street")
                                Destination.confidence=properties.Get(
    "confidence")
                                
    If properties.ContainsKey("distance"Then
                                Destination.distance=properties.Get(
    "distance")
                                
    End If
                                Destination.accuracy=properties.Get(
    "accuracy")
                                Destination.country=properties.Get(
    "country")
                                Destination.country_gid=properties.Get(
    "country_gid")
                                Destination.country_a=properties.Get(
    "country_a")
                                Destination.region=properties.Get(
    "region")
                                Destination.region_gid=properties.Get(
    "region_gid")
                                Destination.region_a=properties.Get(
    "region_a")
                                Destination.county=properties.Get(
    "county")
                                Destination.county_gid=properties.Get(
    "county_gid")
                                Destination.county_a=properties.Get(
    "county_a")
                                Destination.locality=properties.Get(
    "locality")
                                Destination.locality_gid=properties.Get(
    "locality_gid")
                                Destination.continent=properties.Get(
    "continent")
                                Destination.continent_gid=properties.Get(
    "continent_gid")
                                Destination.BoundingBox=bb
                                Destination.label=properties.Get(
    "label")
                           
                                
    Log("DESTINATION SUCCESSFULLY SET  = " & Destination)
                        
    End If
                   
                    
    End If
            
    End If
            job.Release
        
    Else
            
    Log("job was an utter failure")
            job.Release
        
    End If

        job.Release
        
    Log"end of job done")
    End Sub
    #End Region


    #End Region

    #Region make_strings_for_url_requests
    Sub makestringfordirections (Origin1 As geocodedLocation, Destination1 As geocodedLocation)

    ' Look up the updates to the mapquest api http://open.mapquestapi.com/directions/
    Main.mapquesturl ="http://open.mapquestapi.com/guidance/v2/route?key="&Main.mapquestapikey&"&callback=renderAdvancedInformation&outFormat=json&routeType=shortest&narrativeType=text&shapeFormat=raw&generalize=0&generalizeAfter=500&direction=-1&avoidManeuverDuration=-1&unit=k&from="&Origin1.Latitude &","&Origin1.Longitude&"&to="&Destination1.Latitude&","&Destination1.Longitude&"&fishbone=false"
    Log(Main.mapquesturl)
    'send this to web

    'Activity.Finish

    End Sub

    #End Region
    #Region voice

    Sub ButtonVoiceDestAddr_Click
        leavereason = 
    "voice"
        VR.Listen 
    'calls the voice recognition external activity
        Buttonsentvoice = "Destination"
    End Sub

    Sub ButtonVoiceCurrentAddr_Click
        leavereason = 
    "voice"
        VR.Listen 
    'calls the voice recognition external activity
        Buttonsentvoice = "Current"
    End Sub

    Sub VR_Result (Success As Boolean, Texts As List)
        
    If Success = True Then
            
    If Buttonsentvoice = "Current" Then
            EditTextCurrentAddr .Text = Texts.get(
    0)
            
    ' geocode the new origin address
            getORIGINlatlng
            
    End If
           
            
    If Buttonsentvoice = "Destination" Then
            EditTextDestinationAddr .Text = Texts.get(
    0)
            
    End If
           
            TTS1.Speak(Texts.get(
    0), True)
        
    End If
    End Sub
    #End Region

    Sub determineifOriginNeedsGeocoding () As Boolean
        
    Dim result As Boolean
       
        
    If Origin.IsInitialized Then
            
    Dim l As Location
            l.Initialize2(Main.LastLatitude, Main.LastLongitude)
            
    Dim O As Location
            O.Initialize2(Origin.Latitude, Origin.Longitude)
            
    Log("distance  moved since geode, or geocode error is : " & O.DistanceTo(l))
            
    If (O.DistanceTo(l) > 40Then
                
    Log ("weve probably moved from the point we got here with ")
                result = 
    True
            
    End If
           
        
    Else
            result= 
    True
        
    End If
                    
    Return result
    End Sub



    Sub ButtonDebug_Click
        Findcurrentaddressfromlatlng

    End Sub
     
    Last edited: Jun 3, 2019
  2. Computersmith64

    Computersmith64 Well-Known Member Licensed User

    You probably need to do some searching on the forum for topics like Wait For, asynchronous processing, etc...

    There are a lot of tasks that use callbacks to handle the result of a function call - eg: pretty much anything where the result is not returned instantaneously - otherwise an app would be stopping & starting, giving the user a very bad experience. A few off the top of my head:

    * HTTPJob requests (you knew that one already)
    * Database queries
    * Calls to Google Play Games Services
    * Google Maps
    * MsgBoxAsync
    * Network sockets

    If you can be a bit more specific about the actual issue you are having somebody might be able to help you get it sorted.

    - Colin.
     
    jamesnz likes this.
  3. MarkusR

    MarkusR Well-Known Member Licensed User

    jamesnz likes this.
  4. jamesnz

    jamesnz Active Member Licensed User

    The problem is I have a single sub " ButtonGetDirections" that calls two other subs, and those two subs call further subs with web jobs .
    I need both of those web jobs to finish so I can use the result of them to construct a string. but even with the wait-for's in place on the webjob the original sub executes the string construction "makestringfordirections " prior to the webjobs finishing
     
  5. MarkusR

    MarkusR Well-Known Member Licensed User

    i guess u just need one more "wait for" for the sub that contains the web job.
     
  6. jamesnz

    jamesnz Active Member Licensed User

    Yes, this works,
    each calling sub, right back to the activating button needs the 'wait for' with the return handled each time
    cheers

    Code:
    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'These variables can be accessed from all modules.

    End Sub

    Sub Globals
        
    'These global variables will be redeclared each time the activity is created.
        'These variables can only be accessed from this module.
        Dim key As String ="888888888888888" ' mapquest
        Dim OpenRouteAPIKey As String = "88888888888888888888888"
        
    Dim Destination As geocodedLocation
        
    Dim Origin As geocodedLocation
        
    Private EditTextOriginAddr As EditText
        
    Private ButtonGetDirections As Button
        
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        Activity.LoadLayout("Layout1")
        Destination.Initialize
        Origin.Initialize
    End Sub

    Sub Activity_Resume

    End Sub

    Sub Activity_Pause (UserClosed As Boolean)

    End Sub


    Sub determineifOriginNeedsGeocoding () As Boolean
        
    Dim result As Boolean = True
      
            
    Dim l As Location
            l.Initialize2(-
    37.7738616,175.2755251)
            
    Dim O As Location
            O.Initialize2(Origin.Latitude, Origin.Longitude)
            
            
    Log("distance  moved since geode, or geocode error is : " & O.DistanceTo(l))
            
    ' if distance is close then we must have geocoded recently
            If (O.DistanceTo(l) < 40Then
                
    Log ("weve probably moved from the point we got here with ")
                result = 
    False
            
    End If
              
        
    Return result
    End Sub

    Sub Findcurrentaddressfromlatlng
    'if we have gps we use the lat/lng to find the address string and display it to the user
    'run by resume
    'If Main.LastLatitude <> 0 Then
    If True = True Then
        
    'AddressfromLatLng(Main.LastLatitude, Main.LastLongitude,"origin")
        AddressfromLatLng(-37.77378175.27516,"origin")
        EditTextOriginAddr.Text=
    ""
        EditTextOriginAddr.Text = Origin.label
    Else
        
    Log"GPS is zero")
        EditTextOriginAddr.RequestFocus
    End If
    End Sub


    Sub ButtonGetDirections_Click
    Log("fired get directions click event")
        
    If Origin.Latitude = 0 Then
            
    Log("Origin not geocoded, geocoding Origin")
             
    wait for (getORIGINlatlng) Complete (result As Boolean)
        
    End If
        
    ButtonGetDirections.text = EditTextOriginAddr.Text & 
    " " & "25 Opoia St hamilton NZ "
     
    wait for (getdestlatlng) complete ( result As Boolean)

    makestringfordirections (Origin , Destination )
    If Destination.Latitude= 0 Then
        
    ' geocode any ungeocoded fields
        

        
    End If
    End Sub


    Sub getdestlatlng As ResumableSub
        
    wait for (LatLngFromAddress("25 opoia rd hamilton new zealand","destination")) Complete (Result As Boolean)
        
    Return Result
    End Sub


    Sub getORIGINlatlng As ResumableSub
        EditTextOriginAddr.Text=
    "450 river rd hamilton"
        
    If EditTextOriginAddr.Text.Length>3 Then

            
    ' add nz to end of current_address string
            Dim LocationName2 As String
            
    If EditTextOriginAddr.Text.ToUpperCase.Contains ("NZ"Or  EditTextOriginAddr.Text.ToUpperCase.Contains ("NEW ZEALAND"Then
                
    Log("contains nz")
            
    Else
                
    Log("added nz")
                EditTextOriginAddr.Text = EditTextOriginAddr.Text  & 
    " NZ"
            
    End If
        
            LocationName2=EditTextOriginAddr .Text
        
            
    wait for (LatLngFromAddress(LocationName2,"origin")) complete (Result As Boolean)
            
    Log("result from latlng from address was "& Result)
        
    Else
            
    ToastMessageShow"in the top box. tell us where you are"True)
            
    ' if we have gps we need to run find address from latlng
        End If
        
    Return Result
    End Sub



    Sub LatLngFromAddress( address As String,purpose As String)As ResumableSub
        
        
    ' SENDS AN ADDRESS STRING FOR GEOCODING - returns a lat lng
        Dim job2 As HttpJob
        job2.Initialize(
    "geocodeaddresstolatlng",Me)
        job2.Tag=purpose
        
        
        job2.Download2(
    "https://api.openrouteservice.org/geocode/search",     Array As String("api_key", OpenRouteAPIKey, "text"address))
        
    Log(job2)
        
        
    Wait For (job2) JobDone(job As HttpJob)
        
    Log("This should be the job "&job)
        
    If job.Success = True Then
            
    Log(job.GetString)
            ProcessReturn(job)
        
    End If
        job.Release
        
    Return job.Success
    End Sub

    Sub AddressfromLatLng( latitude As Float , longitude As Float, purpose As String)
    ' SENDS LAT/LNG pair for REVERSE GEOCODING - returns an address string
        'leavereason="geocode"
        Dim job1 As HttpJob
        job1.Initialize(
    "ORSCoordinatesToAddress",Me)
        job1.Tag = purpose
        job1.Download(
    "https://api.openrouteservice.org/geocode/reverse?api_key=88888888888&point.lon="& longitude &"&point.lat="& latitude &"boundary.circle.radius=.1&size=2&sources=openstreetmap")
        
        
    Wait For (job1) JobDone(job As HttpJob)
        
    If job.Success = True Then
        
    Log(job.GetString)
        ProcessReturn(job)
        job.Release
        
    End If
        
        
    End Sub
        
        
        
    Sub  ProcessReturn (job As HttpJob)

    Log("Process return tag"&job.Tag)

        
    If job.Success = True Then
        
            
    Log(job.GetString)
                
    If job.Tag ="origin" Or job.Tag="destination" Then
                    
    Dim jp As JSONParser
                    jp.Initialize(job.GetString)
                    
    Dim m As Map = jp.NextObject
            
                    
    Dim results As List = m.Get("features")
                    
    Dim bb As List = m.Get("bbox")
                    
    If results.Size > 0 Then
                        
    Dim first As Map = results.Get(0)
                        
    Dim geometry As Map = first.Get("geometry")
                        
    Dim properties As Map = first.Get("properties")
                        
                        
    'Log("this is the property map"& properties)
                        
                        
    Dim coordinates As List = geometry.Get("coordinates")
                    
                        
    If job.Tag="origin" Then
                            Origin.latitude= coordinates.Get(
    1)
                            Origin.Longitude =coordinates.Get(
    0)
                            Origin.gid=properties.Get(
    "id")
                            Origin.id=properties.Get(
    "gid")
                            Origin.layer=properties.Get(
    "layer")
                            Origin.source=properties.Get(
    "source")
                            Origin.source_id=properties.Get(
    "source_id")
                            Origin.name=properties.Get(
    "name")
                            Origin.housenumber=properties.Get(
    "housenumber")
                            Origin.street=properties.Get(
    "street")
                            Origin.confidence=properties.Get(
    "confidence")
                            
    If properties.ContainsKey("distance"Then
                            Origin.distance=properties.Get(
    "distance")
                            
    End If
                            Origin.accuracy=properties.Get(
    "accuracy")
                            Origin.country=properties.Get(
    "country")
                            Origin.country_gid=properties.Get(
    "country_gid")
                            Origin.country_a=properties.Get(
    "country_a")
                            Origin.region=properties.Get(
    "region")
                            Origin.region_gid=properties.Get(
    "region_gid")
                            Origin.region_a=properties.Get(
    "region_a")
                            Origin.county=properties.Get(
    "county")
                            Origin.county_gid=properties.Get(
    "county_gid")
                            Origin.county_a=properties.Get(
    "county_a")
                            Origin.locality=properties.Get(
    "locality")
                            Origin.locality_gid=properties.Get(
    "locality_gid")
                            Origin.continent=properties.Get(
    "continent")
                            Origin.continent_gid=properties.Get(
    "continent_gid")
                            Origin.label=properties.Get(
    "label")
                            Origin.BoundingBox=bb
                            
    Log("Origin SUCCESFULLY SET = " & Origin)
                            
                        
    else if job.Tag ="destination" Then
                        
                                Destination.latitude= coordinates.Get(
    1)
                                Destination.Longitude =coordinates.Get(
    0)
                                 Destination.gid=properties.Get(
    "id")
                                Destination.id=properties.Get(
    "gid")
                                Destination.layer=properties.Get(
    "layer")
                                Destination.source=properties.Get(
    "source")
                                Destination.source_id=properties.Get(
    "source_id")
                                Destination.name=properties.Get(
    "name")
                                Destination.housenumber=properties.Get(
    "housenumber")
                                Destination.street=properties.Get(
    "street")
                                Destination.confidence=properties.Get(
    "confidence")
                                
    If properties.ContainsKey("distance"Then
                                Destination.distance=properties.Get(
    "distance")
                                
    End If
                                Destination.accuracy=properties.Get(
    "accuracy")
                                Destination.country=properties.Get(
    "country")
                                Destination.country_gid=properties.Get(
    "country_gid")
                                Destination.country_a=properties.Get(
    "country_a")
                                Destination.region=properties.Get(
    "region")
                                Destination.region_gid=properties.Get(
    "region_gid")
                                Destination.region_a=properties.Get(
    "region_a")
                                Destination.county=properties.Get(
    "county")
                                Destination.county_gid=properties.Get(
    "county_gid")
                                Destination.county_a=properties.Get(
    "county_a")
                                Destination.locality=properties.Get(
    "locality")
                                Destination.locality_gid=properties.Get(
    "locality_gid")
                                Destination.continent=properties.Get(
    "continent")
                                Destination.continent_gid=properties.Get(
    "continent_gid")
                                Destination.BoundingBox=bb
                                Destination.label=properties.Get(
    "label")
                            
                                
    Log("DESTINATION SUCCESSFULLY SET  = " & Destination)
                        
    End If
                    
                    
    End If
            
    End If
            job.Release
        
    Else
            
    Log("job was an utter failure")
            job.Release
        
    End If

        job.Release
        
    Log"end of job done")
    End Sub


    Sub makestringfordirections (Origin1 As geocodedLocation, Destination1 As geocodedLocation)

        
    ' Look up the updates to the mapquest api http://open.mapquestapi.com/directions/
        Dim mapquesturl As String  ="http://open.mapquestapi.com/guidance/v2/route?key="&key&"&callback=renderAdvancedInformation&outFormat=json&routeType=shortest&narrativeType=text&shapeFormat=raw&generalize=0&generalizeAfter=500&direction=-1&avoidManeuverDuration=-1&unit=k&from="&Origin1.Latitude &","&Origin1.Longitude&"&to="&Destination1.Latitude&","&Destination1.Longitude&"&fishbone=false"
        
    Log(mapquesturl)
        
    'send this to web

        
    'Activity.Finish

    End Sub
     
    MarkusR likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice