Android Question cancel a loop

hi
i have a loop like this:

B4X:
for i=0 to 1000

    ...do works...
 
 next

and i want that if user press back_key or my_back_key , the loop stop running .

But this does not happen and the activity_KeyPress or my_back_key_Click sub is executed after the execution of the loop.
i tried sleep(0) and DoEvents in loop .
 

JohnC

Expert
Licensed User
Longtime User
Setup a global Boolean variable called AbortLoop and use this code:
B4X:
AbortLoop = False
For i = 1 To 1000
    .....do works....
    If AbortLoop = True Then Exit
Next

Then set AbortLoop = True elsewhere to have the loop exit - but keep in mind that any code AFTER the loop will then run, so if you don't want that then add another check of AbortLoop after the loop to handle that situation.
 
Last edited:
Upvote 0

MicroDrie

Well-Known Member
Licensed User
You can also give the loop counter the maximum value which lead to a completion of the loop with the first loop test after it. This approach doesn't lead to unpredictable behavior and hard to find error when the loop counter is tested outside the loop.
 
Upvote 0
Then set AbortLoop = True elsewhere to have the loop exit - but keep in mind that any code AFTER the loop will then run, so if you don't want that then add another check of AbortLoop after the loop to handle that situation.
Thank you John
i already use it but i cant set AbortLoop=true when the loop is running, because activity_KeyPress sub raised after the execution of the loop.(In fact, even after running the loop, the activity_KeyPress sub is not automatically raised and the back button must be touched again! However, it is not possible to change the value of the AbortLoop during execution of loop)

This code will only work is there is a call to Sleep or Wait For inside the loop (though without it, it will complete very quickly).
Thank you Erel
I test sleep and DoEvents inside the loop But it was not useful and the activity_KeyPress sub is not raised during execution of loop.
And I used the Wait for in different ways, but I didn't find the right way to use it in this case
What is the correct method?
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Curious, how many seconds does the loop take to run through the 1000 count?

Also, can you post the code you have in the Activity_Keypress sub?
 
Upvote 0
You need to provide more information because it is not clear what you are doing.

Sure
Thanks in advance for your time

I am developing a book software (includes 20 chapters and about 200 pages per chapter)
In the activity where the text of a chapter of the book is to be displayed, I have a scroll view, first (in the Activity_Create) I will add a white panel to the scroll view to the total number of pages of the chapter:

B4X:
           For i=1 To number_of_pages
                Sleep(0)
                If check_back Then Exit
                Dim p As Panel
                p.Initialize("p")
                p.Tag=0
                p.Color=Colors.White
                sv.Panel.AddView( p , 5%x , (85%y+2%y)*i , 90%x , 85%y )
            Next

In another sub , for pages that are visible, the contents are taken from the database and added to the panel :
B4X:
Sub change_visable_Range_on_jump(VisablePage As Int)

    Dim Range_down As Int = Max(1,VisablePage-4)
    Dim Range_up As Int = Min(tedadsafhe,VisablePage+4)
  
    For i=1 To Range_down-1
        If check_back Then Exit
        Dim p As Panel=sv.Panel.GetView(i-1)
        If p .Tag=1 Then
             p.RemoveAllViews
             p.Tag=0
        End If
    Next
  
    For i=Range_down To Range_up
        If check_back Then Exit
        Dim p As Panel=sv.Panel.GetView(i-1)
        If p .Tag=0 Then  CallSubDelayed2(Me,"add_page", i)
    Next
  
    For i=Range_up+1 To tedadsafhe
        If check_back Then Exit
        Dim p As Panel=sv.Panel.GetView(i-1)
        If p .Tag=1 Then
            p.RemoveAllViews
            p.Tag=0
        End If
    Next
End Sub

add_page sub::
Sub add_page(page1 As Object)

If check_back=False Then

    Dim page As Int = page1
    dim p as panel = sv.Panel.GetView(page-1)
    c=sql.ExecQuery("select * from tbl where page = "&page &" and chapter = "&chapter)
    For j=0 To c.RowCount-1
            Sleep(0)
            c.Position=j
            If  c.GetString("value").Contains("text") Then
                      dim l as label
                      l.text=c.getString
                       p.addview( l , ....)
             end if
          
            If  c.GetString("value").Contains("image") Then
                       .....add imageView to p....
             end if
  
             If  c.GetString("value").Contains("math") Then
                       .....add KatexMathView to p....
             end if
             .
             .
             .         
    next
end sub


All the codes work well and there are only two problems: the first and most important problem is that when running each of the loops, the software temporarily hangs, and if the return button is touched at that time, the activity_KeyPress sub does not come up And is ignored.
The second problem is related to the same short interruption when performing loops, because it causes the scrolling of the scrollView to be done with a tick and a break, and it does not slip smoothly.
Is it possible to run the loops in one service or another place so that they do not interrupt the main function? What is the correct way to run long and engaging loops?


urious, how many seconds does the loop take to run through the 1000 count?

I wrote the number one thousand, for example
Running speed depends on the power of the device, but running a full season on an activity takes about 10 to 20 seconds. Of course, I only add the first few pages, and the rest of the pages will be added if the view is scrolled, in which case it will take about 5 to 10 seconds at first.

Also, can you post the code you have in the Activity_Keypress sub?

B4X:
Sub activity_KeyPress (KeyCode As Int) As Boolean 'Return True to consume the event
    If KeyCode=KeyCodes.KEYCODE_BACK Then
            check_back=True
            Activity.Finish
    End If
    Return True
End Sub
 
Last edited:
Upvote 0
Better to use xCLV.
Dear Earl
The xCLV has a big problem, and that is that you can't scroll to a specific position, for example, if we consider each page of the book as an item in the xCLV, suppose a page in my book is about 140%y high , and the user searches for the text at the bottom of the page. So I have to put the scroll position in the middle of the page to show bottom of the page and search result . but you can't pinpoint the exact location with the xCLV, you can only go to the TOP position of a particular item.
 
Upvote 0
Top