Reflection library - how to call B4A subs?

jgmdavies

Member
Licensed User
Longtime User
The Tricks of the Trade wiki entry shows this code:

B4X:
Sub Process_Globals
   Dim debugMode As Boolean
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
       Dim r As Reflector
       debugMode = r.GetStaticField("anywheresoftware.b4a.BA", "debugMode")
   End If
   Log(debugMode)
End Sub

The above works well, but I can't see how to use any of the various Reflection 'method' methods to invoke one of my B4A subs - is this possible please?

Example (in the main Activity):

B4X:
sub MySub1
    Log("MySub1")
end sub

sub Try
   Dim r As Reflector

   r.Target = Me
   Log("Reflection version: " & r.Version)

        ' THESE ALL FAIL WITH a 'java.lang.NoSuchMethodException':

   r.RunMethod("MySub1")
   r.RunPublicmethod("MySub1", Null, Null)
   r.RunStaticMethod("anywheresoftware.b4a.BA", "MySub1", Null, Null)
   m = r.GetMethod("MySub1",Null)

end sub

Would someone point me in the right direction please? (And yes, I have a 'valid' use for this!)

Thanks,
Jim
 

corwin42

Expert
Licensed User
Longtime User
Have a look into the generated source code. Your Sub will be renamed to _mysub1 I think.

But why do you want to call Subs with Reflection if there are native methods like CallSub for this in B4A?
 
Upvote 0

jgmdavies

Member
Licensed User
Longtime User
Danke corwin42 and The DesolateSoul.

I looked at the generated java and tried prepending an underscore to the sub names and making them all lower-case, but no joy.

To clarify what I'm after, I'm trying to discover the names of subs in the user code.

I'm thinking of an approach to unit testing, where I would scan all the user code for test routines (which would be 'normal' subs, but using a specified naming convention). This is quite common in unit test frameworks, and saves having to keep modifying a list of test routines somewhere.

Jim
 
Last edited:
Upvote 0

jgmdavies

Member
Licensed User
Longtime User
Thanks - I initially looked for something like a 'getDeclaredMethods' in Reflector, but then retreated to just seeing if I could call one! (So my bit about discovery is out of context - sorry.)

I guess this might also help someone writing a documentation utility, e.g. perhaps in conjunction with this forum idea.
 
Upvote 0

jgmdavies

Member
Licensed User
Longtime User
For anyone interested, the following works for calling a sub via Reflector:

B4X:
r.RunStaticMethod("b4a.example.main", "_test__1", Null, Null)

where the 2nd argument (the method name) should be the name of your sub (in the 'main' activity, in this case), with one underscore added at the start, and all lower-case (see the generated java files if you're not sure).

My example sub is:

B4X:
Sub Test__1

   Log("Test__1")

End Sub
 
Last edited:
Upvote 0
Top