B4J Question Serializing and storing customtype arrays?

techknight

Well-Known Member
Licensed User
Longtime User
I know this was discussed in the past, and I may have brought it up in the past but sadly its lost in conversation and I cannot find it.

But I am struggling trying to figure out a way to store object arrays of custom types into a WriteB4XObject function.

I tried B4XSerializator but it still didnt work, keeps crashing.

Here is the declaration:
B4X:
    Type GameClockData (Deciseconds As Int, MaxDeciSeconds As Int, ClockSet As Boolean, ClockStopped As Boolean, ClockDirection As Int)   

Public PenaltyClock(2) As GameClockData

Snippet of the test subroutine:
B4X:
    Try
        If AppSettings.ContainsKey("PenaltyClock") = True Then
            Dim Serializer As B4XSerializator
            Log(AppSettings.Get("PenaltyClock"))
            ScoreEngine.PenaltyClock = Serializer.ConvertBytesToObject(AppSettings.Get("PenaltyClock"))
        Else
            For I = 0 To ScoreEngine.PenaltyClock.Length-1
                ScoreEngine.PenaltyClock(I).Initialize
                ScoreEngine.PenaltyClock(I).ClockStopped = True
                ScoreEngine.PenaltyClock(I).ClockSet = False
                ScoreEngine.PenaltyClock(I).Deciseconds = 0
                ScoreEngine.PenaltyClock(I).ClockDirection = 0       
            Next
        End If   
    Catch
        For I = 0 To ScoreEngine.PenaltyClock.Length-1
            ScoreEngine.PenaltyClock(I).Initialize
            ScoreEngine.PenaltyClock(I).ClockStopped = True
            ScoreEngine.PenaltyClock(I).ClockSet = False
            ScoreEngine.PenaltyClock(I).Deciseconds = 0
            ScoreEngine.PenaltyClock(I).ClockDirection = 0       
        Next
    End Try

my "write" routine:
B4X:
Sub WriteConfig
    Dim R As RandomAccessFile
    Dim AppSettings As Map
    Dim Serializer As B4XSerializator
    R.Initialize(File.DirInternal, "settingsv2.ini", False)
    AppSettings.Initialize
    AppSettings.Put("ConfigVersion", ConfigVersion)
    AppSettings.Put("ConnectionProperties", CommEngine.ConnectionProperties)
    AppSettings.Put("Brightnessval", CommEngine.Brightnessval)
    AppSettings.Put("TeamName", ScoreEngine.TeamName)
    AppSettings.Put("GameOptions", ScoreEngine.GameOptions)
    AppSettings.Put("Paintball", ScoreEngine.Paintball)
    AppSettings.Put("GameClock", ScoreEngine.GameClock)
    AppSettings.Put("BreakClock", ScoreEngine.BreakClock)
    AppSettings.Put("PenaltyClock", Serializer.ConvertObjectToBytes(ScoreEngine.PenaltyClock))
    R.WriteB4XObject(AppSettings, 0)
    R.Close
End Sub

Trouble is, I keep getting crashes such as:
B4X:
Error occurred on line: 924 (Main)
java.lang.IllegalArgumentException: field md.smpaintball1b.scoreengine._penaltyclock has type md.smpaintball1b.scoreengine$_gameclockdata[], got java.lang.Object[]
    at java.lang.reflect.Field.set(Native Method)
    at anywheresoftware.b4a.shell.Shell.setStateBeforeUserSub(Shell.java:509)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:411)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
    at md.smpaintball1b.main._readconfig(main.java:689)
    at md.smpaintball1b.main._activity_create(main.java:582)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at md.smpaintball1b.main.afterFirstLayout(main.java:105)
    at md.smpaintball1b.main.access$000(main.java:17)
    at md.smpaintball1b.main$WaitForLayout.run(main.java:83)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6823)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1557)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
** Activity (main) Resume **

line 924 is the actual End Sub statement, so the line number its providing is somehow invalid.

Prior to using serializator, I was trying to store the array directly into the Map, but it failed with similar crashes, it would also cause the array to be null and would no longer work right and crash elsewhere.

I am sure there is a way to fix it, but it escapes me at the moment

thanks
 

techknight

Well-Known Member
Licensed User
Longtime User
I had to throw it in a list, which seemed to work that time
1645479246289.png
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
B4XSerializator doesn't do Arrays of Primitives as objects.
However, I have tried Lists that hold Arrays of Primitives, and it seemed to work.
I don't know why.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I made some tests, the commented out version does not work (as warned by the system).
But it is not too constraining since to second version works fine.

I still don't why, but it has something to do with how arrays of primitives are implemented (efficiency?, legacy?, Java?)
Note 1: inline .As(Int) also doesn't work with Arrays.
Note 2: Arrays of Objects can't be assigned to Arrays of primitives (automatic conversion is not done)

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
'    Type xType(a() As Int)            OR
'    Type xType(a() As Object)        in Class_Globals

    Private xType1 As xType
    xType1.Initialize

    Private xList1 As List
    xList1.Initialize

    Private xObject1 As Object

    Dim ser As B4XSerializator

'    Dim ar() As Int = Array As Int(0, 1, 2, 3, 4)
'    xType1.a = ar1
'    xList1.Add(ar1)
'    xObject1 = ar1

'    Dim xType2 As xType = ser.ConvertBytesToObject(ser.ConvertObjectToBytes(xType1))
'    Dim ax() As Int = xType2.a
'    Log(ax(2))

'    Dim xList2 As List = ser.ConvertBytesToObject(ser.ConvertObjectToBytes(xList1))
'    Dim ax() As Int = xList2.Get(1)
'    Log(ax(2))

'    Dim xObject2 As Object = ser.ConvertBytesToObject(ser.ConvertObjectToBytes(xObject1))
'    Dim ax() As Int = xObject2
'    Log(ax(2))

    Dim ar1() As Object = Array(0, 1, 2, 3, 4)
    xType1.a = ar1
    xList1.Add(ar1)
    xObject1 = ar1

    Dim xType2 As xType = ser.ConvertBytesToObject(ser.ConvertObjectToBytes(xType1))
    Dim ax() As Object = xType2.a
    Log(ax(2))

    Dim xList2 As List = ser.ConvertBytesToObject(ser.ConvertObjectToBytes(xList1))
    Dim ax() As Object = xList2.Get(0)
    Log(ax(2))

    Dim xObject2 As Object = ser.ConvertBytesToObject(ser.ConvertObjectToBytes(xObject1))
    Dim ax() As Object = xObject2
    Log(ax(2))

End Sub
 
Upvote 0
Top