Android Question B4XPages and ResumableSub

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Just starting with B4XPages and noticed that ResumableSub is not behaving the same as in a non B4XPages project.
In an activity based project I can run this from Main with no problem:

B4X:
    Dim rs As ResumableSub = CSV2List(File.DirRootExternal & "/PhonePats", "menu_props2.csv", True, 44, 34, True, 10, -1)
    Wait For (rs) Complete (lstCSV As List)
    
    Log(lstCSV.Size)

and I can use the produced list fine.

In a B4XPages project though I get this error:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to anywheresoftware.b4a.BA$ResumableSub

If I run this not as a ResumableSub:

B4X:
    Dim lstCSV As List
    
    lstCSV = CSV2List(File.DirRootExternal & "/PhonePats", "menu_props2.csv", True, 44, 34, True, 10, -1)

    Log(lstCSV.Size)

There is no problem.
Is this a known limitation of B4XPages or am I doing something wrong?

RBS
 

klaus

Expert
Licensed User
Longtime User
You might replace the line above by this one.

B4X:
'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=\%PROJECT_NAME%.zip

%PROJECT_NAME% is a reserved word for the project name.
I use it it in all my B4XPages projects.
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
The app crash because it cannot find the CSV file in the position where it search for.
The only way I got to make it work is to follow @LucaMs solution to copy the CSV file from ASSETS to DIRINTERNAL.
In this way I got the list created by CSV2LIST (maybe with other changes, but now I downloaded your last version).
Anyway in ASSETS we have menu_props, while you search for menu_props2.
Are we missing something?
And anyway it throw an error on item 29 or 30 of the list while parsing it because of an EMPTY STRING.
Of course I can't analize all your app to understand what it should do. ;) šŸ˜…
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
The app crash because it cannot find the CSV file in the position where it search for.
The only way I got to make it work is to follow @LucaMs solution to copy the CSV file from ASSETS to DIRINTERNAL.
In this way I got the list created by CSV2LIST (maybe with other changes, but now I downloaded your last version).
Anyway in ASSETS we have menu_props, while you search for menu_props2.
Are we missing something?
And anyway it throw an error on item 29 or 30 of the list while parsing it because of an EMPTY STRING.
Of course I can't analize all your app to understand what it should do. ;) šŸ˜…
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Ignore the .csv files in dirassets. I am testing only with the file that I copied to that phonepats folder via Windows file explorer via the USB connection. There are no empty strings in the .csv I posted.

RBS
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
OK, I missed the post where you posted that file.
Created the PhonePats folder, copied the file................. It works.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
OK, I missed the post where you posted that file.
Created the PhonePats folder, copied the file................. It works.
I made it work by making the Sub MakeMenuArray Resumable. With me if I make that Sub non-Resumable I get the problem as mentioned.

RBS
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
The fact is that MakeMenuArray contain a Wait For instructions.
Any Sub that contain a Sleep or a Wait For become a Resumable Sub (check Here).
So to return a value it's needed the
B4X:
as ResumableSub
at the end.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
The fact is that MakeMenuArray contain a Wait For instructions.
Any Sub that contain a Sleep or a Wait For become a Resumable Sub (check Here).
So to return a value it's needed the
B4X:
as ResumableSub
at the end.
OK, thanks, I think that might be the solution. I thought that in the non B4XPages project it worked, but that must be wrong. Will check that in bit.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
The fact is that MakeMenuArray contain a Wait For instructions.
Any Sub that contain a Sleep or a Wait For become a Resumable Sub (check Here).
So to return a value it's needed the
B4X:
as ResumableSub
at the end.
I checked in the other non-B4XPages project and there are Subs that contain a Wait For and those Subs are called normally (not as ResumableSub) and that is fine
if that Sub with the Wait For doesn't return a value. In the MenuTest project the Sub MakeMenuArray wasn't returning a value, but still I was unable to call it as a non-ResumableSub. This is the difference. So, it seems to me that if a Sub contains a Wait For that Sub can be called as a non-ResumableSub, provided that Sub returns no value.
So, still not sure why it fails in this B4XPages project.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I checked in the other non-B4XPages project and there are Subs that contain a Wait For and those Subs are called normally (not as ResumableSub) and that is fine
if that Sub with the Wait For doesn't return a value. In the MenuTest project the Sub MakeMenuArray wasn't returning a value, but still I was unable to call it as a non-ResumableSub. This is the difference. So, it seems to me that if a Sub contains a Wait For that Sub can be called as a non-ResumableSub, provided that Sub returns no value.
So, still not sure why it fails in this B4XPages project.

RBS

>> - You can wait for resumable subs in other modules (in B4A it is relevant for classes only).

As a B4XPage is class, maybe this is relevant.

RBS
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
Your Sub in the end contain a
Return True
If this it's not needed I think that you can remove it and then probably you can even remove the
as ResumableSub
suffix.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Your Sub in the end contain a
Return True
If this it's not needed I think that you can remove it and then probably you can even remove the
as ResumableSub
suffix.
I only added the Return True when I made it a Resumable Sub. Without making MakeMenuArray a ResumableSub I couldn't get it to work.
Can you make it work without making MakeMenuArray a ResumableSub and with CSV2List being a ResumableSub?

RBS
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
It's not possible to use your project exactly as it is, because we don't have the file in DirRootExternal (that's not the right way to access it, by the way).

However, in general:

if a sub contains a Wait For or a Sleep, it automatically becomes of type ResumableSub. It is possible to call it both with and without "Wait For" but you must bear in mind that the project flow will continue after its invocation.

Anyway, change the name to one of the two ResumableSub variables; they are both RS, inside the same Sub(B4XPage_Created), so the second one redefines the other.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
It's not possible to use your project exactly as it is, because we don't have the file in DirRootExternal (that's not the right way to access it, by the way).

However, in general:

if a sub contains a Wait For or a Sleep, it automatically becomes of type ResumableSub. It is possible to call it both with and without "Wait For" but you must bear in mind that the project flow will continue after its invocation.

Anyway, change the name to one of the two ResumableSub variables; they are both RS, inside the same Sub(B4XPage_Created), so the second one redefines the other.
I posted the .csv file

> that's not the right way to access it, by the way
How should it be done instead?

> change the name to one of the two ResumableSub variables
OK, wasn't aware that could be a problem, will change that.

RBS
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Screenshot_20230101-190047.jpg


(but using File.DirInternal)
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
Correct me if I am wrong.
In this part of your code
B4X:
If bDone Then
       
        '----------
        'this works
        '----------
        Dim rs As ResumableSub = MakeMenuArray
        Wait For (rs) Complete (dDoneMenuArray As Boolean)
       
        '-----------------
        'this doesn't work
        '-----------------
'        MakeMenuArray

        For i = iButtonStartIndex To arrMenuButtons.Length - 1 'overflow button has no bitmap
            arrMenuButtons(i).SetBitmap(arrMenu(i).bmpIconBitMap1) '<<<<< java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
        Next

    End If
after the MakeMenuArray you have a For cycle that need
B4X:
arrMenu(i).bmpIconBitMap1
to be ready. This is done by MakeMenuArray.
Calling MakeMenuArray as a normal Sub seems not to leave enough time to the Sub to complete its job before the next operations.
This is why using it as a Resumable Sub solve the problem.
As a confirmation, if you put a Sleep to let it complete
B4X:
If bDone Then
       
        '----------
        'this works
        '----------
'        Dim rs As ResumableSub = MakeMenuArray
'        Wait For (rs) Complete (dDoneMenuArray As Boolean)
       
        '-----------------
        'this doesn't work
        '-----------------
        MakeMenuArray
       
        Sleep(1000) 'Let us give time to MakeMenuArray to complete (exagerated value)
       
        For i = iButtonStartIndex To arrMenuButtons.Length - 1 'overflow button has no bitmap
            arrMenuButtons(i).SetBitmap(arrMenu(i).bmpIconBitMap1) '<<<<< java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
        Next

    End If
then you can have your Sub like this
B4X:
Sub MakeMenuArray
    'Do things
    'More things
    'Yet more things
End Sub
But honestly I would prefer a Resumable Sub that just wait for the exact time needed by the Sub to complete.
 

Attachments

  • MenuTest_With_Sleep.zip
    165.3 KB · Views: 50
Upvote 0
Top