Bug? Global (not Process Global) variable's value gets changed in another Activity

Inman

Well-Known Member
Licensed User
Longtime User
I am not sure if this is the normal behavior for a custom data type. This is what I did.

I have 3 modules - Main (Activity), Second (Activity), Global (Code)

This is Main activity
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Type VariableType(a,b As Int)
    Dim variable As VariableType
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    Activity.Title="Main Activity"
    variable.Initialize
    variable.a=10
   
End Sub

Sub Activity_Resume
    Msgbox(variable,"Variable")
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub Activity_KeyPress (KeyCode As Int) As Boolean 'Return True to consume the event
    If keycode=KeyCodes.KEYCODE_MENU Then
        Global.GlobalV=variable
        StartActivity(Second)
    End If
End Sub


This is Global code module
B4X:
'Code module
'Subs in this code module will be accessible from all modules.
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim GlobalV As VariableType
End Sub
This is Second activity
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim secondv As VariableType
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    Activity.Title="Second Activity"
    secondv.Initialize
    secondv=Global.GlobalV
    secondv.a=39
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Run the app. You will see a msgbox that shows the value of variable.a as 10. Now press Menu button to load Second activity. Now press back button to get back to the Main activity. Now the msgbox will show the value of variable.a as 39.

Is this the normal behavior? I was under the impression that the value of only Process Global variables can be changed from another activity. I am attaching a small project (under 10 lines) to show this issue.
 

Attachments

  • Variable Scope Test.zip
    6.9 KB · Views: 153

Erel

B4X founder
Staff member
Licensed User
Longtime User
Not a bug.

B4X:
Global.GlobalV=variable
Now Global.GlobalV and Main.variable point to the same object

B4X:
secondv.Initialize '<-- this line doesn't do anything as you are assigning another object in the next line
secondv=Global.GlobalV
Now Global.GlobalV, Main.variable and Second.secondv point to the same object

B4X:
secondv.a=39
The value of the 'a' field on this single object is now 39.
 

Inman

Well-Known Member
Licensed User
Longtime User
Oh my. Looks like I will have to change a lot of code :)

So, what is the right way to pass values from Main Activity to Second activity such that the value in Main activity remains unchanged?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The issue here is not really related to passing values between modules (which should mostly be done with CallSubDelayed). The issue here is that you need to understand that a custom type is an object. If you want to create a copy of this object then the simple way is to write:
B4X:
Sub CopyMyType(v As VariableType) As VariableType
 Dim n As VariableType
 n.Initialize
 n.a = v.a
 n.b = v.b
 Return n
End Sub
Now you can use this sub to make copies of the original variable.

B4X:
CallSubDelayed2(second, "DoSomething", CopyMyType(variable))
 

Inman

Well-Known Member
Licensed User
Longtime User
Oh ok. Sadly I have like 15 variables include my custom type, one of which is another custom type. :(

I wish there was a way to iterate through all types within a custom type, using a loop, like in a Map object.
 

Inman

Well-Known Member
Licensed User
Longtime User
You mean using a file? I just implemented something like that but with normal RandomAccessFile instead of KVS and it works correctly. Fortunately all my fields are supported by RAF.WriteObject.
 
Top