Android Question How to serialize class objects

jfranz

Member
Licensed User
I have been attempting to find a solution to saving the state of class objects for a couple of days now. I have researched the StateManager as well as the KeyValueStore but they only do simple data plus Types. This morning I looked into JsonGenerator in hopes that this might be a solution but it doesn't look like it does what I need.

A brief example would be a class called Games has a few int and string properties along with a collection (List) of another class called Points. My code currently has a few other classes but lets keep it simple for now. Here are two classes with some of the Class_Globals for each class.

B4X:
Class Point
sub Class_Globals
    private _ServingPlayer as int
    private _PointTo as int
end sub
end class

Class Game
sub Class_Globals
    private _Score(2) as int
    private _ServingTeam as int
    private _Points as List   ' Contains Point objects
end sub

end class

What I need to do is to save the state of this class using something like StateManager but not sure how to do this with B4A. Normally I would think of doing something like Game.Serialize but it looks like I need do everything manually. Is there a better solution than manually creating the serialize myself? I have thought that maybe I could replace simple classes with just a type but I loose the ability to add support for special handling of the properties in each class then.

I hopes this makes sense. What I'm hoping for is something simple like Game.Serialize() and Game.Deserialize(str) or even Game = XYZ.Deserialize(str)

Thanks for any info/guidenance on this.
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
KeyValueStore can handle complex data (like a List with arrays of custom types). However classes cannot be automatically serialized because of the context they hold.

There are several ways to manually implement class serialization.

For example something like:
B4X:
'Class game
Sub ToMap As Map
Dim m As Map
m.Initialize
m.Put("Score", Score)
m.Put("ServiceTeam", ServiceTeam)
Dim pp As List
pp.Initialize
For Each p As Point In Points
  pp.Add(p.ToMap)
Next
m.Put("Points", pp)
End Sub

Sub FromMap(m As Map)
Score = m.Get("Score")
ServiceTeam = m.Get("ServiceTeam")
Dim pp As List = m.Get("Points")
For Each mp As Map in PP
  Dim p As Point
  p.Initialize
  p.FromMap(mp)
  Points.Add(p)
Next
End Sub

'Class point
Sub ToMap As Map
Dim m As Map
m.Initialize
m.Put("ServingPlayer", ServingPlayer)
m.Put("PointTo", PointTo)
Return m
End Sub

Now you just need to call Game.ToMap and save the returned map with KVS.
 
Upvote 0

LucaMs

Expert
Licensed User
It may be helpful to use a routine to save (and reload) all variables related to the properties of the class.

Maybe we could use a special syntax as jfranz has already done using the underscore.

I'm trying. There are difficulties with arrays, they must already be dimensioned, but maybe I'll be able to do something (and post).
 
Upvote 0

jfranz

Member
Licensed User
Thanks for your help with this. I was hoping for a more generic way that I was overlooking. Something maybe using reflection and json. Maybe something I should look into if I can figure out how to get reflection to return all attributes/variables in a class.

I decided after thinking about it for a while to implement it in XML so I can use the same logic to store in a DB for history and for handling state. I can't seem to convert the map to a string so gave up on that and switched to XML.

Thanks anyway for the help.
 
Upvote 0

LucaMs

Expert
Licensed User
"how to get reflection to return all attributes/variables in a class"

This would be ideal, but I do not know if it's possible.
 
Upvote 0
Top