Android Question Wait For usage for blocking operations

udg

Expert
Licensed User
Longtime User
Hi all,
finally I've some time to experiment the possibilites introduced with WaitFor and say farewell to JobDone.
Let me briefly describe what I'm doing to convert my code.

I have a sub (called in Activity.Create after layout loading) which uses two ancillary subs to retrive data from a remote server in order to properly construct the UI.
So the whole setup sequence should be: SetUI-FirstSub-SecondSub.
What's mandatory is that SecondSub shouldn't start before FirstSub is done. So I have tooled things this way:
B4X:
Sub SetUI
   'do some initial stuff here
   FirstSub(a_parameter)
   Wait For FirstSub_Complete
   'use data returned from server in FirstSub to build the UI
   SecondSub
   Wait For SecondSub_Complete
   'use data from SecondSub to populate the UI
End Sub

Sub FirstSub(a_parameter As Int)
   'set parameters to send to remote server
   Dim buffer() As Byte = PrepareCommand(Parameters, Cmd) '<- my solution before RDC was available
   Dim pJob As HttpJob
   pJob.Initialize("", Me)
   pJob.PostBytes(Starter.hurl&"/myservice",buffer)
   Wait For(pJob) JobDone(j As HttpJob)
   If j.Success Then
     'code to read back data from server and make it available to SetUI and activity context
   Else
     Log("Error: " & j.ErrorMessage)
     ToastMessageShow("Error: " & j.ErrorMessage, True)
   End If
   j.Release
   CallSubDelayed(Me, "FirstSub_Complete")
End Sub

Sub SecondSub
   'structurally similar to FirstSub
   CallSubDelayed(Me, "SecondSub_Complete")
End Sub
My question: did I use WaitFor correctly?

If I understood it correctly, the sequence of actions should be:
CreateSub - Start SetUI - Start FirstSub - Return to SetUI on hitting WF - return to Create because of first WF in SetUI - FirstSub completes- SetUI can proceed- Start SecondSub - Return to SetUI on hitting WF - return to Create because of second WF in SetUI- SecondSub completes - SeUI can proceed and completes - Return to Create.
Note that SetUI is the last instruction in CreateSub.

TIA
 

udg

Expert
Licensed User
Longtime User
Thanks Erel. I knew it was too clumsy to be entirely correct.
If I understand it correctly, I should recode my subs as below:
B4X:
Sub SetUI
  'do some initial stuff here
  Wait For(FirstSub(a_parameter)) Complete (Result As Object)
  'use data returned from server in FirstSub to build the UI
  Wait For(SecondSub) Complete (Result As Object)
  'use data from SecondSub to populate the UI
End Sub

Sub FirstSub(a_parameter As Int) As ResumableSub
  'set parameters to send to remote server
  Dim buffer() As Byte = PrepareCommand(Parameters, Cmd) '<- my solution before RDC was available
  Dim pJob As HttpJob
  pJob.Initialize("", Me)
  pJob.PostBytes(Starter.hurl&"/myservice",buffer)
  Wait For(pJob) JobDone(j As HttpJob)
  If j.Success Then
      'code to read back data from server and make it available to SetUI and activity context
  Else
      Log("Error: " & j.ErrorMessage)
      ToastMessageShow("Error: " & j.ErrorMessage, True)
  End If
  j.Release
  Return null  <-- here I could return what now goes to a global var
End Sub

Sub SecondSub As ResumableSub
  'structurally similar to FirstSub
  Return null
End Sub

In other words, it seems that the introduction of "As ResumableSub" made it obsolete the use of CallSubDelay function.
Since I'd like to fully understand the subject, can you briefly comment on the differences between my initial post and the current one (supposing the code is now 100% correct); I mean, was the former wrong or simply clumsy and obsolete?
A second question: is the sequence of actions described at the bottom of post#1 correct? Did I understand the flow of action? TIA.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Returning ResumableSub is cleaner and also allows multiple calls to the same resumable sub. This is not possible with CallSubDelayed.

For example you can create a sub that returns an image:
B4X:
Sub DownloadImage (url As String) As ResumableSub
 Dim j As HttpJob
 j.Initialize(Me, "")
 j.Download(url)
 Wait For (j) JobDone(j As HttpJob)
Dim bmp As Bitmap
 If j.Success Then
  bmp  = j.GetBitmap
Else
 bmp = ErrorBitmap
 End 
 j.Release
 Return bmp
End Sub

You can call it multiple times from anywhere you like and the correct result will reach the correct calling usb.

The flow is very simple. It calls FirstSub and waits for it to complete. It then calls SecondSub and waits for it to complete.
 
  • Like
Reactions: udg
Upvote 0
Top