如何使用Thread.UncaughtExceptionHandler获取抛出异常的行号?

时间:2014-05-28 05:59:21

标签: android

当我使用try-catch块来捕获异常时,我可以通过调用e.getStackTrace()来获取抛出异常的行号。

像这样:

java.lang.NumberFormatException: Invalid int: "abc"    
java.lang.Integer.invalidInt(Integer.java:138)   
java.lang.Integer.parse(Integer.java:375)   
java.lang.Integer.parseInt(Integer.java:366)   
java.lang.Integer.parseInt(Integer.java:332)   
com.example.getarea.MainActivity.onCreate(MainActivity.java:42)   
android.app.Activity.performCreate(Activity.java:5066)   
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1102)   
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)   
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)   
android.app.ActivityThread.access$600(ActivityThread.java:151)   
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1330)   
android.os.Handler.dispatchMessage(Handler.java:99)   
android.os.Looper.loop(Looper.java:155)   
android.app.ActivityThread.main(ActivityThread.java:5536)   
java.lang.reflect.Method.invokeNative(Native Method)   
java.lang.reflect.Method.invoke(Method.java:511)   
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1074)   
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:841)   
dalvik.system.NativeStart.main(Native Method) 

但是当我使用Thread.UncaughtExceptionHandler时,调用e.getStackTrace()给我这个:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.getarea/com.example.getarea.MainActivity}: java.lang.NumberFormatException: Invalid int: "abc"    
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)        
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)        
android.app.ActivityThread.access$600(ActivityThread.java:151)        
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1330)        
android.os.Handler.dispatchMessage(Handler.java:99)        
android.os.Looper.loop(Looper.java:155)        
android.app.ActivityThread.main(ActivityThread.java:5536)        
java.lang.reflect.Method.invokeNative(Native Method)        
java.lang.reflect.Method.invoke(Method.java:511)        
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1074)        
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:841)        
dalvik.system.NativeStart.main(Native Method)  

如何使用Thread.UncaughtExceptionHandler获取引发异常的行号?

3 个答案:

答案 0 :(得分:32)

尝试

e.getStackTrace()[0].getLineNumber();

堆栈跟踪中的第一个元素是最近调用的方法(调用堆栈的顶部)。

还有获取类,方法和文件名的方法。

如果你在UncaughtExceptionHandler中遇到的e对你不好(因为它包装了真正的异常),你可以尝试e.getCause()并查看该堆栈跟踪。

答案 1 :(得分:1)

受到Thilo和范植胜的启发,这里为懒人提供了复制'粘贴版本:

public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    final Thread.UncaughtExceptionHandler uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        Log.ee(thread.getClass().getName(),
                throwable.getMessage(),
                "Error in " + Arrays.toString(throwable.getCause().getStackTrace()));
        if (uncaughtExceptionHandler != null) {
            // let Android know what happened
            uncaughtExceptionHandler.uncaughtException(thread, throwable);
        } else {
            // kill process
            System.exit(-1);
        }
    }
}

注意:Log.ee是自定义文件编写器

public static void ee(String tag, String msg, String msg2) {
    try {
        String ts = Utils.getReadableTimeStamp();
        File dir = new File(Environment.getExternalStorageDirectory() + "/" + Const.CRASH_DIR);
        dir.mkdirs();
        PrintWriter printWriter = new PrintWriter(new FileWriter(new File(dir, "errors-" + sImei + ".log"), true));
        printWriter.print("-------------------------------\r\n");
        printWriter.print(ts + ":\r\n");
        printWriter.print(tag + "\r\n");
        printWriter.print(msg + "\r\n");
        printWriter.print(msg2 + "\r\n");
        printWriter.print("-------------------------------\r\n");
        printWriter.flush();
    } catch (IOException e) {
        android.util.Log.e(Log.class.getName(), "ee -> IOException", e);
    }
}

答案 2 :(得分:0)

Exception 类的函数 printStackTrace() 可以接受一个参数,PrintStream 或 PrintWriter。因此,可以使用 StringWriter 将堆栈跟踪打印到字符串中:

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
sw.toString() //will return the stack trace as a String.

https://www.baeldung.com/java-stacktrace-to-string