Android Question Line Number or Method Name

Marco Nissen

Active Member
Licensed User
Longtime User
Hi

is it possible to get the current line number or method name as a variable similar to LastException?

I would like to standardize my logging, which is currently showing the current activity, but unfortunately the debug logger links to the line where the Log() method call is placed.

here are some example code snippets that I liked to use to have standardized debug output

any ideas?

thanks
marco


B4X:
Sub LogInfo(info As String)
    Dim title As String = myActivity.Title
    Log("ℹ️ " & title.touppercase & ": " & info)
End Sub

B4X:
Sub LogException
    Dim message As String
    Dim title As String = myActivity.Title
    message = "❌ " & title.touppercase & ": " & LastException.Message
    Log(message)
End Sub


found this code snippet (see link), maybe it is useful

B4X:
/**
 * Get the method name for a depth in call stack. <br />
 * Utility function
 * @param depth depth in the call stack (0 means current method, 1 means call method, ...)
 * @return method name
 */
public static String getMethodName(final int depth)
{
  final StackTraceElement[] ste = Thread.currentThread().getStackTrace();

  //System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
  // return ste[ste.length - depth].getMethodName();  //Wrong, fails for depth = 0
  return ste[ste.length - 1 - depth].getMethodName(); //Thank you Tom Tresansky
}
 

Spavlyuk

Active Member
Licensed User
I was thinking of something similar as well. I've written an class that logs to a file (in addition to the default log) and the link going to an irrelevant line has been a bit annoying.
My suggestion would be to perhaps add a Log2 method that takes an additional int argument of how many methods to skip in the current stacktrace before generating a link.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Really not sure, was a bit of a longshot as it was originally for B4J (not sure anyone tried on B4A - I certainly didn't).
 
Last edited:
Upvote 0

Marco Nissen

Active Member
Licensed User
Longtime User
Really not sure, was a bit of a longshot as it was originally for B4J (not sure anyone tried on B4A - I certainly didn't).
i see.

I think which element of the stack trace to be used to report as calling class/method/line needs to be adjusted based on the call hierarchy.
Therefore I've added a function to report the trace and a number, so I can use the right number.

so the code below is now working for me. note that the position 8 depends on the call hierarchy.
the number belongs to the java code line, but is still helpful for debugging if necessary.
the method name has a leading "_" which could be removed


logging:
Sub LogInfo(info As String)
    LogBase("ℹ️", info)
End Sub
 
Sub LogBase(emoji As String, info As String)
    Dim title As String = ""
    Dim emoji As String = "ℹ️"
    Dim methodName As String = Starter.getMethodName
    Dim linenumber As Int = Starter.getLineNumber
    If myActivity.IsInitialized Then
        title = myActivity.Title
        title = title.ToUpperCase
    Else
        Dim className As String = Starter.getclassname
        title = className.ToUpperCase
    End If
    ' Log("full " & Starter.getFullStackTrace)  ' use to print out full stack trace to see the correct call level
    Log(emoji & "️ " & title & "/" & methodName & "/" & linenumber& ": " & info)
End Sub
 
Sub LogOK(info As String)
    LogBase("✅️",info)
End Sub

Sub LogNOK(info As String)
    LogBase("🚫️",info)
End Sub

Sub LogIssue(info As String)
    LogBase("❌️",info)
End Sub
 
Sub LogException
    LogBase("❌",LastException.Message)
End Sub

starter:
 #If JAVA
import android.util.Log;

public static String getMethodNameJAVA() {
  StackTraceElement[] ste = Thread.currentThread().getStackTrace();
  return ste[8].getMethodName();
}
public static int getLineNumberJAVA() {
  StackTraceElement[] ste = Thread.currentThread().getStackTrace();
  return ste[8].getLineNumber();
}
public static String getClassNameJAVA() {
  StackTraceElement[] ste = Thread.currentThread().getStackTrace();
  return ste[8].getClassName();
}
public static String getFullStackTraceJAVA() {
    StackTraceElement[] ste = Thread.currentThread().getStackTrace();
    StringBuilder sb = new StringBuilder();
    int i = 0;
      for (StackTraceElement trace : ste) {
        sb.append(i + ": " + trace.toString() + "\n");
        i++;
      }
      return sb.toString();
}
#End If
 
Sub getMethodName As String
    Dim mName As String = (Me).As(JavaObject).RunMethod("getMethodNameJAVA",Null)
    Return mName
End Sub

Sub getFullStackTrace As String
    Dim full As String = (Me).As(JavaObject).RunMethod("getFullStackTraceJAVA",Null)
    Return full
End Sub

Sub getLineNumber As Int
    Dim lineNo As Int = (Me).As(JavaObject).RunMethod("getLineNumberJAVA",Null)
    Return lineNo
End Sub

Sub getClassName As String
    Dim cName As String = (Me).As(JavaObject).RunMethod("getClassNameJAVA",Null)
    Return cName
End Sub
 
Last edited:
Upvote 0
Top