Android Question Initializing the field of a custom type with reflector or javaobject

TelKel81

Active Member
Licensed User
For each field (they are all maps) of a custom type, I want to initialize its map.

I know I can use JavaObject / Reflection to do it but I can't find out how.
 

stevel05

Expert
Licensed User
Longtime User
I know I can use JavaObject / Reflection to do it but I can't find out how.
You could, but it would be simpler to create a sub that does it.

B4X:
Public Sub CreateMapType as MapType
    Dim MT as MapType
    MT.Initialize
    MT.Map1.Initialize
    MT.Map2.Initialize
    'etc ....
    Return MT
End sub
Where Map1, Ma2 etc are whatever you've called the map variable within the type.

Then call as

B4X:
Dim MT as MapType = CreateMapType
 
Upvote 0

TelKel81

Active Member
Licensed User
I have a lot of maps to initialize in a lot of types, so I'd rather create a sub that iterates through the fields of those types and initialize any map.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
It would be messy, and I would wager that unless you have several hundred types, it would be quicker to create a code module, put all the CreateType Subs in there and selectively search and replace to edit the code.
 
Upvote 0

TelKel81

Active Member
Licensed User
I don't see the one-liner Init.Maps(OfThisType) as more messy than a Sub full of This.Initialize somewhere in my class.

My goal is to avoid having to type each name of a map that's in a type... I'd like to pass the custom type as a parameter to a sub that will iterate through each field of the custom type and initialize if it's a map.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Try this:

B4X:
Public Sub InitializeMaps(Class As Object)
  
    Dim R As Reflector
    R.Target = Class.As(JavaObject).RunMethod("getClass",Null)
    Dim Fields() As Object = R.RunMethod("getFields")
    For Each Field As JavaObject In Fields
        Dim F As JavaObject = Class.As(JavaObject).GetField(Field.RunMethod("getName",Null))
        Dim FType As String = GetType(F)
'        If  FType = "anywheresoftware.b4a.objects.collections.Map" Or FType = "anywheresoftware.b4a.objects.collections.List" Then
        If FType = "anywheresoftware.b4a.objects.collections.Map" Then
            F.RunMethod("Initialize",Null)
        End If
    Next
End Sub

The commented line will do lists as well, just swap them around. It wasn't as bad as I thought as I remembered I had code in a old app that was similar.

BUT, please test it thoroughly. And be aware that because of the hardcoding of the class names it will break if they ever change..
 
Last edited:
Upvote 0

TelKel81

Active Member
Licensed User
I'm trying to do the same with B4XOrderedMap but the method to initialize it is different :
public java.lang.String b4a.example.b4xorderedmap._initialize(b4a.example.b4xorderedmap,anywheresoftware.b4a.BA)

And I get this error when running its _initialize method : java.lang.RuntimeException: Method: _initialize not matched.
Which is different from "method not found"... and I found nothing with "not matched" in the forums :(
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Try it this way:
B4X:
Public Sub InitializeMaps(Class As Object)
 
    Dim R As Reflector
    R.Target = Class.As(JavaObject).RunMethod("getClass",Null)
    Dim Fields() As Object = R.RunMethod("getFields")
    For Each Field As JavaObject In Fields
        Dim F As Object = Class.As(JavaObject).GetField(Field.RunMethod("getName",Null))
        Dim FType As String = GetType(F)
        '        If  FType = "anywheresoftware.b4a.objects.collections.Map" Or FType = "anywheresoftware.b4a.objects.collections.List" Then
        If FType = "anywheresoftware.b4a.objects.collections.Map" Then
            F.As(JavaObject).RunMethod("Initialize",Null)
        Else If F Is B4XOrderedMap Then
            F.As(B4XOrderedMap).Initialize
        End If
    Next
End Sub
 
Upvote 0
Top