Android Question reflection access class methods

mterveen

Member
Licensed User
Longtime User
developed a program back in 2013 that used this code (as an example):

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.

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")
   Enumerate
End Sub

Sub Enumerate
    Dim c As myclass
    c.Initialize
    Dim r1, r2 As Reflector
    r2.Target=c
    r1.Target=r2.RunMethod("getClass")
    Dim Fields() As Object = r1.RunMethod("getDeclaredFields")
    For Each Field As Object In Fields
          r1.Target=Field
          Dim vname As String = r1.RunMethod("getName")
          If vname.StartsWith("_v_") Then
          Log(vname)
          Log(r2.GetField(vname))
          Dim getter As String = vname.Replace("_v_","_get")
              Log(r2.RunMethod(getter))           '***** this line bombs*******
        End If
    Next
End Sub

with this class:
B4X:
'Class module
Sub Class_Globals
    Private v_i As Int = 10
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
End Sub

Sub seti(e As Int)
  v_i = e
End Sub
Sub geti As Int
  Return v_i
End Sub

recently i had to modify some non related code in the program. now when i run this routine i get the following error:

** Activity (main) Create, isFirst = true **
_v_i
10
Error occurred on line: 47 (Main)
java.lang.NoSuchMethodException: _geti []
at java.lang.Class.getDeclaredMethod(Class.java:635)
at anywheresoftware.b4a.agraham.reflection.Reflection.runmethod(Reflection.java:214)
at anywheresoftware.b4a.agraham.reflection.Reflection.RunMethod(Reflection.java:802)
at b4a.example.main._enumerate(main.java:415)
at b4a.example.main._activity_create(main.java:352)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:697)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:336)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at b4a.example.main.afterFirstLayout(main.java:102)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
** Activity (main) Resume **

what changed and how do i fix it?
 
Last edited:

mterveen

Member
Licensed User
Longtime User
i have a class that contains all the properties (set/get) for a gauge component. i then create a list of all these properities and allow the user to change the values. so i use a loop to read the name and current value of each property. then when complete i run the "set" property to update the value. btw, the setr doesn't work either anymore! the example above just shows how i access the data. i was able to get the "get" to work with the following code:

B4X:
    Dim args(1) As Object
    Dim types(1) As String
    args(0) = c ' the object whose field to access
    types(0) = "java.lang.Object" ' get method parameter type
    Dim getter as string = "_geti"
    Log(r2.RunMethod2(getter,args,types))

the set side of things has be baffled tho. the android syntax for both is:

get(Object object)
set(Object object, Object value)

i could use an answer for the set! ;) spent way too much time already working on this. would also be curious how a java object could be used instead.
 
Last edited:
Upvote 0

mterveen

Member
Licensed User
Longtime User
not quite what i was hoping for but i guess i can switch to using a map and using callsub(class object, "get" & fieldname). in my testing that technique takes twice as long as doing runmethod4 calls.....
 
Upvote 0
Top