Android Question SetField of a Type with Reflector or JavaObject ?

TelKel81

Active Member
Licensed User
Longtime User
Hi, I want to use a type as an enum and I don't want to set the value of each string of that type since the fieldname IS what the string value will be. How to do it with Reflector or JavaObject ?

B4X:
    Dim r As Reflector
    r.Target = BiomeType
    r.Target = r.RunMethod("getClass")
    Dim Fields() As Object = r.RunMethod("getDeclaredFields")
    For Each Field As Object In Fields
           r.Target = Field
        Dim name As String = r.RunMethod("getName")
        If name = "IsInitialized" Then Continue
         r.SetField(name,name, "java.lang.string") <--- error 
    Next
    Next

java.lang.NoSuchFieldException: Desert
at java.lang.Class.getDeclaredField(Class.java:2070)

OR : do you suggest another approach entirely. Thanks !
 
The easiest way is to use a Code Module and set the fields as Public Const, they are then accessible anywhere. Something like:
B4X:
Public Const FIELD1 As String = "Field1"
Public Const FIELD2 As String = "Field2"
Public Const FIELD3 As String = "Field3"
Public Const FIELD4 As String = "Field4"
 
Upvote 0
Thanks for the tip but I wish to use types so that if I change the name of the fields or add a couple in a row, I don't have to create/define a new const for each one of them.
 
Upvote 0
I don't think you will be able to change the fields defined in a class (which a type is under the hood) during program execution.
 
Upvote 0
So I should conclude that there is no JavaObject or Reflector trick that would allow me to set the value of a string field in a type ?
 
Upvote 0
The following code is in B4J but it should be trivial to port it to B4A.
It's an adaptation of the code that was kindly provided to me by @Roycefer here^
Code:
'Non-UI application (console / server application)
#Region Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

Sub Process_Globals
    Type BiomeType(t1 As String, t2 As String, t3 As String, t4 As String)
End Sub

Sub AppStart (Args() As String)
    Dim t As BiomeType
    t.Initialize
    t=TypeToType(t)
    Log(t)
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub TypeToType(o As Object) As Object
    Dim r As Reflector
    r.Target = o
    Dim jo As JavaObject = Me
    Dim fields() As String = jo.RunMethod("GetFields", Array(o))
    For Each f As String In fields
        If f="IsInitialized" Then Continue
        r.SetField(f,f,"java.lang.String")
    Next
    Return o
End Sub

#If JAVA
import java.lang.reflect.Field;
public static String[] GetFields(Object o)
{
    Class oc = o.getClass();
    Field[] fields = oc.getDeclaredFields();
    String[] res = new String[fields.length] ;
    for(int j=0;j<fields.length;j++)
    {
       res[j] = fields[j].getName();
    }
    return res;
}
#End If
 
Upvote 0
Very nice ! Exactly what I wanted. Thanks a lot !
What if I wanted to also get the fields of a code module ?
 
Upvote 0
Back
Top