Android Code Snippet Log Calling Class and Method

I've created a utility function that allows you to automatically log the class and method from which a function was called. I currently need this in our very large project where different classes call the same function. This makes it easier to debug where the call came from.
Below is the code for the LogCaller function, which uses JavaObject to access the stack trace and determine the calling class and method.

Note on Stack Trace Position
The position 5 in the stack trace (StackTrace(5)) is chosen based on my case. However, if you have a chain of method calls, this position might need to be adjusted. For instance, if there are multiple nested calls, the index might need to be higher or lower to correctly capture the calling method and class.
You can experiment with the stack trace index to ensure it correctly identifies the calling method. You can do this by logging the entire stack trace and analyzing the positions

B4X:
Sub LogCaller
    Dim ST As JavaObject
    ST.InitializeStatic("java.lang.Thread")
    Dim CurrentThread As JavaObject = ST.RunMethod("currentThread", Null)
    Dim StackTrace() As Object = CurrentThread.RunMethod("getStackTrace", Null)
    Dim ClassName As String = StackTrace(5).As(JavaObject).RunMethod("getClassName", Null)
    Dim MethodName As String = StackTrace(5).As(JavaObject).RunMethod("getMethodName", Null)
    Log("Called from Class: " & ClassName & ", Method: " & MethodName)
End Sub

ClassB.bas
B4X:
Sub Class_Globals
    ' Declare your global variables here.
End Sub

Public Sub Initialize
    ' Initialization code here.
End Sub

Public Sub SomeFunction
    LogCaller
    ' Other code for the function.
End Sub

ClassA.bas
B4X:
Sub Class_Globals
    ' Declare your global variables here.
    Private b As ClassB
End Sub

Public Sub Initialize
    b.Initialize
End Sub

Public Sub SomeFunctionInA
    b.SomeFunction
End Sub

Result
B4X:
Called from Class: de.dinotec.netplus.ClassA, Method: SomeFunctionInA
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
I think many years ago I asked if it was possible to achieve exactly this.

About that literal 5: what the project, that sub, should usually care about is the last call; it is therefore necessary to understand whether the stack is FIFO or LIFO, whether the zero index or StackTrace.Length -1 should be used and also be able to empty the stack.

I'll look up the Java methods used; also, I will also try with B4J, as I think it should work with this one too.


Thanks for sharing, @Blueforcer
 

LucaMs

Expert
Licensed User
Longtime User
About that literal 5: what the project, that sub, should usually care about is the last call; it is therefore necessary to understand whether the stack is FIFO or LIFO, whether the zero index or StackTrace.Length -1 should be used and also be able to empty the stack.

🤔🤔🤔

DEBUG MODE - After pausing the app and resumed it:

Called from Class: anywheresoftware.b4a.shell.Shell

Method: runMethod
Line: 732

StackTrace length 33

0 dalvik.system.VMStack getThreadStackTrace

1 java.lang.Thread getStackTrace

2 java.lang.reflect.Method invoke

3 anywheresoftware.b4j.object.JavaObject RunMethod

4 java.lang.reflect.Method invoke

5 anywheresoftware.b4a.shell.Shell runMethod

6 anywheresoftware.b4a.shell.Shell raiseEventImpl

7 anywheresoftware.b4a.shell.Shell raiseEvent

8 java.lang.reflect.Method invoke

9 anywheresoftware.b4a.ShellBA raiseEvent2

10 anywheresoftware.b4a.debug.Debug delegate

11 b4a.example.classb _logcaller

12 b4a.example.classb _somefunction

13 b4a.example.classa _somefunctionina


14 b4a.example.main _button1_click

15 java.lang.reflect.Method invoke

16 anywheresoftware.b4a.shell.Shell runMethod

17 anywheresoftware.b4a.shell.Shell raiseEventImpl

18 anywheresoftware.b4a.shell.Shell raiseEvent

19 java.lang.reflect.Method invoke

20 anywheresoftware.b4a.ShellBA raiseEvent2

21 anywheresoftware.b4a.BA raiseEvent2

22 anywheresoftware.b4a.BA raiseEvent

23 anywheresoftware.b4a.objects.ViewWrapper$1 onClick

24 android.view.View performClick

25 android.view.View$PerformClick run

26 android.os.Handler handleCallback

27 android.os.Handler dispatchMessage

28 android.os.Looper loop

29 android.app.ActivityThread main

30 java.lang.reflect.Method invoke

31 com.android.internal.os.Zygote$MethodAndArgsCaller run

32 com.android.internal.os.ZygoteInit main




DEBUG MODE - WITHOUT pausing the app:


Called from Class: b4a.example.classb

Method: _somefunction
Line: 57

StackTrace length 26

0 dalvik.system.VMStack getThreadStackTrace

1 java.lang.Thread getStackTrace

2 java.lang.reflect.Method invoke

3 anywheresoftware.b4j.object.JavaObject RunMethod

4 b4a.example.classb _logcaller

5 b4a.example.classb _somefunction

6 b4a.example.classa _somefunctionina


7 b4a.example.main _button1_click

8 java.lang.reflect.Method invoke

9 anywheresoftware.b4a.shell.Shell runMethod

10 anywheresoftware.b4a.shell.Shell raiseEventImpl

11 anywheresoftware.b4a.shell.Shell raiseEvent

12 java.lang.reflect.Method invoke

13 anywheresoftware.b4a.ShellBA raiseEvent2

14 anywheresoftware.b4a.BA raiseEvent2

15 anywheresoftware.b4a.BA raiseEvent

16 anywheresoftware.b4a.objects.ViewWrapper$1 onClick

17 android.view.View performClick

18 android.view.View$PerformClick run

19 android.os.Handler handleCallback

20 android.os.Handler dispatchMessage

21 android.os.Looper loop

22 android.app.ActivityThread main

23 java.lang.reflect.Method invoke

24 com.android.internal.os.Zygote$MethodAndArgsCaller run

25 com.android.internal.os.ZygoteInit main
 

LucaMs

Expert
Licensed User
Longtime User
Note on Stack Trace Position
The position 5 in the stack trace (StackTrace(5)) is chosen based on my case. However, if you have a chain of method calls, this position might need to be adjusted. For instance, if there are multiple nested calls, the index might need to be higher or lower to correctly capture the calling method and class.
You can experiment with the stack trace index to ensure it correctly identifies the calling method. You can do this by logging the entire stack trace and analyzing the positions
Just take the next StackTrace item after the one which called method is LogCaller (if you don't change the Sub LogCaller name)

1715789968381.png





1715790020514.png
 
Top