Android Question Wait For inside Threading always escape

Steve Kwok

Member
Licensed User
Hi, All.
I would like to download data from internet periodically by background thread.
With reference to:
Threading library
https://www.b4x.com/android/forum/threads/threading-library.6775/,
I changed the code as follow but get freezed :(

98rd4h.jpg

B4X:
Sub ThreadSub3
    'Dim Count As Int = 0
    Dim Params(1) As Object
    Dim ok3 As Boolean = False
    Dim trying As Int = 0
    Dim Count As Int
    Do While Count < 1000
        Count = Count + 1
        Params(0) = Count
        sendPhpTimeIntent
        Wait For getJobResponse(map_1 As Map)
        StopService(svcPhpTime)
        LogColor("Start time: " & map_1.Get("start"), Colors.Blue)
        LogColor("End time: " & map_1.Get("end"), Colors.Blue)
        '******************************************
        'This not work and get freeze!!!
        Do Until ok3
            'Count = Count + 1
            Params(0) = Count
            ' this is because Android seems to lose the run message if the user presses back button
            ' this way no message will be ignored
            Thread3.RunOnGuiThread("Update3", Params)
            ok3 = Lock3.WaitFor(1000)
            If ok3 Then
                LogColor("ok3's value: " & ok3 & " with trying: " & trying, Colors.Blue)
            Else
                LogColor("ok3's value: " & ok3 & " with trying: " & trying, Colors.Red)
            End If
            trying = trying + 1
        Loop
    Loop
 
End Sub

if I skip Do Until ... Loop, it seems work.
2qv6rvd.jpg

B4X:
Sub ThreadSub3
    'Dim Count As Int = 0
    Dim Params(1) As Object
    Dim ok3 As Boolean = False
    Dim trying As Int = 0
    Dim Count As Int
    Do While Count < 1000
        Count = Count + 1
        Params(0) = Count
        sendPhpTimeIntent
        Wait For getJobResponse(map_1 As Map)
        StopService(svcPhpTime)
        LogColor("Start time: " & map_1.Get("start"), Colors.Blue)
        LogColor("End time: " & map_1.Get("end"), Colors.Blue)
        '*****************************************
'        This Work!
        Thread3.RunOnGuiThread("Update3", Params)
    Loop
 
End Sub

Php Code with file name: sleepfor1sec.php:
PHP:
<?php
// displaying time
$start = date('h:i:s');
// delaying execution of the script for 5 seconds
sleep(1);
// displaying time again
$end = date('h:i:s');
echo "{\"start\":\"" . $start . "\",\"end\":\"" . $end . "\"}";
?>

It seems that Wait For inside Thread would escape. How can make "wait for" not escape?

Program run in video:
 

Attachments

  • ThreadingDemo_20190715.zip
    16.6 KB · Views: 212
Last edited:

Steve Kwok

Member
Licensed User
Dear DonManfred and Erel,

I try not using thread (i.e. comment Thread3) and directly access the edittext (UI) instead.

ThreadSub3 -> NonThreadSub

B4X:
Sub NonThreadSub
    Dim Count As Int   
    Do While Count < 10
        Count = Count + 1
        sendPhpTimeIntent
        Wait For getJobResponse(map_1 As Map)
        StopService(svcPhpTime)
        LogColor("Start time: " & map_1.Get("start"), Colors.Blue)
        LogColor("End time: " & map_1.Get("end"), Colors.Blue)
        'Thread3.RunOnGuiThread("Update3", Params)
        'Access UI directly
        EditText3.Text = Count
    Loop         
End Sub

Inside the service (HttpJobs):
B4X:
Dim job As HttpJobs

Private Sub Send   
    job.Initialize("", Me)
    job.Download(myUrl)
End Sub

Private Sub JobDone(j As HttpJob)
    If j.Success Then
        Dim isParsedSuccess As Boolean = False
        Try
            isParsedSuccess = parseJson(j.GetString)
        Catch           
            strErrMessage = "svcPhpTime.JobDone:" & LastException.Message
            LogColor(strErrMessage, Colors.Red)
        End Try
        If isParsedSuccess Then
            If IsPaused(mySender) = False Then
                CallSubDelayed2(mySender, "getJobResponse", mapResultPair)
            Else
                Log("JobDone")
                StopService("")
            End If
        Else   
            If IsPaused(mySender) = False Then
                CallSubDelayed2(mySender, "getJobFailureResponse", strErrMessage)
            Else
                Log(strErrMessage)
                StopService("")
            End If
        End If       
    Else
        strErrMessage = j.ErrorMessage
        LogColor("svcPhpTime Error: " & CRLF & strErrMessage, Colors.red)
        If IsPaused(mySender) = False Then
            CallSubDelayed2(mySender, "getJobFailureResponse", "Network Access Error!!!!!!" & CRLF & "Please check the record.")
        Else
            Log("Network Access Error!!!!!!" & CRLF & "Please check the record.")
            StopService("")
        End If
    End If
    j.Release
End Sub

e6ddgj.png


It works without ANR (i.e. Android Not Response). :)

 

Attachments

  • ThreadingDemo_20190715B.zip
    16.8 KB · Views: 201
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

Steve Kwok

Member
Licensed User
Do you means cutting service - svcPhptime and put it all in the activity?
B4X:
Sub NonThreadSub
    Dim Count As Int   
    Do While Count < 10
        Count = Count + 1
        Dim job As HttpJob
        job.Initialize("", Me)
        job.Download( "http://starbuckz.125mb.com/sleepfor5sec.php")
        'Access UI directly
        EditText3.Text = Count
    Loop
End Sub

Private Sub JobDone(j As HttpJob)
    If j.Success Then
        Dim isParsedSuccess As Boolean = False
        Try
            isParsedSuccess = parseJson(j.GetString)
        Catch
            strErrMsg = "svcPhpTime.JobDone:" & LastException.Message
            LogColor(strErrMsg, Colors.Red)
        End Try
        If isParsedSuccess Then           
            Log("JobDone")
        Else           
            Log(strErrMsg)
        End If
    Else
        strErrMsg = j.ErrorMessage
        LogColor("svcPhpTime Error: " & CRLF & strErrMsg, Colors.red)       
        Log("Network Access Error!!!!!!" & CRLF & "Please check the record.")       
    End If
    j.Release
End Sub

Private Sub parseJson(jstr As String) As Boolean
    Dim jParser As JSONParser
    
    Try
        jParser.Initialize(jstr)
        mapResultPair = jParser.NextObject
        Return True
    Catch
        Dim strErrMessage As String = LastException.Message
        LogColor("svcPhpTime.parseJson: " & CRLF & strErrMessage, Colors.Red)
        Return False
    End Try
End Sub
 
Upvote 0

Steve Kwok

Member
Licensed User
Furthermore, it is simplified as:

B4X:
Sub NonThreadSub
    Dim Count As Int  
    Do While Count < 10
        Count = Count + 1
        Dim job As HttpJob
        job.Initialize("", Me)
        job.Download( "http://starbuckz.125mb.com/sleepfor5sec.php")
        Wait For JobDone(j As HttpJob)
        If j.Success Then
            Dim isParsedSuccess As Boolean = False
            Try
                isParsedSuccess = parseJson(j.GetString)
                LogColor("Start time: " & mapResultPair.Get("start"), Colors.Blue)
                LogColor("End time: " & mapResultPair.Get("end"), Colors.Blue)
            Catch
                strErrMsg = "svcPhpTime.JobDone:" & LastException.Message
                LogColor(strErrMsg, Colors.Red)
            End Try
            If isParsedSuccess Then
                Log("JobDone")
            Else
                Log(strErrMsg)
            End If
        Else
            strErrMsg = j.ErrorMessage
            LogColor("svcPhpTime Error: " & CRLF & strErrMsg, Colors.red)
            Log("Network Access Error!!!!!!" & CRLF & "Please check the record.")
        End If
        j.Release
        'Access UI directly
        EditText3.Text = Count
    Loop
End Sub

Private Sub parseJson(jstr As String) As Boolean
    Dim jParser As JSONParser   
    Try
        jParser.Initialize(jstr)
        mapResultPair = jParser.NextObject
        Return True
    Catch
        Dim strErrMessage As String = LastException.Message
        LogColor("svcPhpTime.parseJson: " & CRLF & strErrMessage, Colors.Red)
        Return False
    End Try
End Sub
 
Last edited:
Upvote 0
Top