Android Question [resolved] Pass value to multi array in process_global

AymanA

Member
Licensed User
Hi All,

This is my first post so apologies for any mistakes and let me know how to correct any - I have read the forum rules, the getting started zip folder, so hopefully I won't mess things up :)

I have a two dimension array defined in Process_global for starter, so is there any way that I can pass the variable from sub service_create to the declared array?

B4X:
Sub Process_Globals
    Public xarr As Int
    Public yarr As Int
    Public TwoDarray(xarr,yarr) As String '<---- to this array
End Sub

Sub Service_Create
    xarr = 2 '<--I want to pass this value
    xarr = 2 ' <--I want to pass this value
    TwoDarray(0,0) = "test1" 
    TwoDarray(0,1) = "test2"
    TwoDarray(1,0) = "test3"
    TwoDarray(1,1) = "test4"
    Log(TwoDarray(0,0))
    Log(TwoDarray(0,1))
    Log(TwoDarray(1,0))
    Log(TwoDarray(1,1))
End Sub
Note: removing the line Public TwoDarray(xarr,yarr) As String from process_global and placing in service_create is working fine, but I am trying to pass the variable from service_create as I have DB that the size of the array will be based on it, then the array will be called from Main activity

Thank you for your help on this!
 

emexes

Well-Known Member
Licensed User
I don't quite understand your question, but the answer might be that you can access Public (Process_) Global variables in other modules by prefixing them with the module name, eg, from the Main Activity module, you can access Starter.xarr and Starter.yarr and presumably the array too. And likewise, you can access Main Process_Global variables from other modules by using Main.variablename.

There is a chance that what looks like a two-dimension array to BASIC eyes, is actually implemented as an array-of-one-dimension-arrays by Java (which has some advantages but mostly disadvantages). I'd check that out for you but it's pretty late here in this part of the world, and my brain's already wound down for the night.
 

AymanA

Member
Licensed User
Thank you so much for your reply, I should have included what happens when I run this code! sorry for that, basically when I run it I receive error in logs:

B4X:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
For some reason the values of xarr =2 and yarr =2 in service_create are not passed to the array declaration in the process_global, so I am not sure how to do that.
 

emexes

Well-Known Member
Licensed User
B4X:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
That "length=0" bit makes me even more suspicious that it might be an issue of your 2x2 two-dimensional array being an array-of-one-dimensional-arrays rather than an actual single two-dimensional block of elements.

If you go one design level higher - what are you actually wanting to do? Like, what does this 2x2 array represent?
 

emexes

Well-Known Member
Licensed User
For some reason the values of xarr =2 and yarr =2 in service_create are not passed to the array declaration in the process_global, so I am not sure how to do that.
Righto... start a new project, and in the Starter module replace the Process_Globals and Service_Create Subs with these three Subs:
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

    Public xarr As Int = 3
    Public yarr As Int = 3
    Public TwoDArray(xarr, yarr) As String
 
End Sub

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.
 
    For I = 0 To xarr - 1
        TwoDArray(I, 0) = "N"
        TwoDArray(I, 2) = "S"
    Next
 
    StarterLogTwoDArray
     
    For I = 0 To yarr - 1
        TwoDArray(0, I) = TwoDArray(0, I) & "W"
        TwoDArray(2, I) = TwoDArray(2, I) & "E"
    Next

    StarterLogTwoDArray
 
End Sub

Sub StarterLogTwoDArray
 
    Log("Starter: TwoDArray =")
    For Y = 0 To 2
        Dim LogLine As String = TwoDArray(0, Y)
        For X = 1 To 2
            LogLine = LogLine & ", " & TwoDArray(X, Y)
        Next
        Log(LogLine)
    Next
 
End Sub
and in the Main module replace the Activity_Create Sub with these two Subs:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")

    'Starter.Service_Create should have already initialized these variables and arrays...
 
    Log("xarr = " & Starter.xarr)
    Log("yarr = " & Starter.yarr)
    MainLogTwoDArray
    CallSub(Starter, "StarterLogTwoDArray")    'to be sure, to be sure
 
End Sub

Sub MainLogTwoDArray
 
    Log("Main: TwoDArray =")
    For Y = 0 To 2
        Dim LogLine As String = Starter.TwoDArray(0, Y)
        For X = 1 To 2
            LogLine = LogLine & ", " & Starter.TwoDArray(X, Y)
        Next
        Log(LogLine)
    Next
 
End Sub
and when you run it in Debug mode (or enable logging in Release mode) you should get a Log like this:

MultidimensionalArrayLog.png
 
Last edited:

emexes

Well-Known Member
Licensed User
I am still mildly suspicious of the multi-dimensional-array bit - yeah, it all works ok here, but... when I went to do TwoDArray.Length, it only returns an Int (ie, singular, implying one-dimensional). Perhaps it should be TwoDArray.Length gives the array size in the x-dimension, and TwoDArray(0).Length gives the array size in the y-dimension (for x = 0... hmm, can the y-dimension size be different for each x?)

Anyway, it's raceday here, and I've fallen behind in getting my investments lodged, so... I'll leave the above for you to experiment with ;-)
 

AymanA

Member
Licensed User
Thank you so much emexes this is so helpful really appreciate your help and the effort spent on this!

If you do not mind I have another question, so what if I have a sqlite db in the starter service and the size of the xarr and yarr are unknown until the database table loads, how to achieve that? I will write the code based on your example and will post today with the database part
 

emexes

Well-Known Member
Licensed User
the size of the xarr and yarr are unknown until the database table loads, how to achieve that?
No problem, you can Dim the array anywhere and anytime you like, the array anywhere and anytime you like, doesn't have to happen in the Service_Create or Activity_Create routine. Just make sure you don't access the array before you've Dim'ed it and ideally not before you've loaded it up with the values from the database or wherever the array data comes from.

Consider having a simple flag to indicate whether the array is ready to use or not, eg:

B4X:
Dim ArrayReadyFlag As Boolean = False

'do other stuff
'get XSize and YSize

Dim A(XSize, YSize) as String

'load up A()
ArrayReadyFlag = True
even if you don't think you'll need it... it's cheap (one byte of memory and a few CPU cycles) and perhaps one day it will save you ;-)
 

emexes

Well-Known Member
Licensed User
Note that Dim has two functions, and they can be done separately or together.

First is to declare to B4A the data type of the array, eg:

Dim A() As Int

so that B4A knows what to do when you refer to A() in your program.

Second is to actually allocate memory for the array, eg:

Dim A(30) As Int

will allocate 120 bytes of memory to hold the 30 Ints (an Int is a 32-bit number = four 8-bit bytes). Obviously your program can't actually store/retrieve data to/from the array until memory has been allocated to hold that data.
 

AymanA

Member
Licensed User
Thank you so much for your help, I will play around with all what I have learnt from your posts!
 
Top