簡體   English   中英

如何使用 Thread.setDefaultUncaughtExceptionHandler?

[英]How to use Thread.setDefaultUncaughtExceptionHandler?

我的應用程序有多個選項卡,每個選項卡都有一個 RecyclerView。 通過單擊 RecyclerView 項, ReadRecentNewsActivity打開。 我在onClick上設置了共享視圖轉換。

問題出在onClick本身,而大部分時間ReadRecentNewsActivity都可以正確啟動,但在某些新聞項目上卻顯示此錯誤。

我認為此錯誤是由於共享轉換造成的,但我不想將其刪除,而是想捕獲此異常並在沒有共享轉換的情況下打開該特定新聞項...

在此處輸入圖片說明

如何使用 Thread.setDefaultUncaughtExceptionHandler?

您正在詢問如何制作自定義錯誤處理程序,以便您可以捕獲此特定異常並確定它是什么。 是的,每個開發人員都應該為他們的應用程序定制一個錯誤處理程序。

實際上,使用自定義錯誤處理程序,您可以通過文件名、方法甚至行號確定異常發生的位置。

下面提供的是我個人使用的錯誤處理程序。 拿一份副本,然后做你想做的事。

將此調用放入您的 Activity 的 onCreate() 例程中:

 ErrorHandler.toCatch(this);

反過來,它將調用 Thread.setDefaultUncaughtExceptionHandler 例程:

  Thread.setDefaultUncaughtExceptionHandler(new ErrorHandler(activity));

錯誤處理程序實現了java.lang.Thread.UncaughtExceptionHandler並因此具有方法 uncaughtException(Thread thread, Throwable exception) 來處理任何異常。

public class ErrorHandler implements java.lang.Thread.UncaughtExceptionHandler{}

通過 ErrorHandler.java 搜索到方法reportErrorHelper.reportError的第 624 行。 然后您可以使用您的 IDE(例如 Android Studio)在那里放置一個斷點,現在每次出現錯誤時,它都會停在那里,您將有一些信息可以繼續。

  public class ErrorHandler implements
    java.lang.Thread.UncaughtExceptionHandler{


private ErrorHandler(Activity activity){

    mPackageName = getPackageName(activity);
}



public static ErrorHandler getINSTANCE(Activity activity){

    if (mErrorHandler == null){

        mErrorHandler = new ErrorHandler(activity);
    }

    return mErrorHandler;
}


private static String getPackageName(Context pContext){

    String packageName = "";

    try{

        ActivityManager activityManager = (ActivityManager) pContext
                .getSystemService(Context.ACTIVITY_SERVICE);

        if (Build.VERSION.SDK_INT > 20){

            packageName = activityManager.getRunningAppProcesses().get(0).processName;
        }else{

            // <uses-permission android:name="android.permission.GET_TASKS" />
            packageName = activityManager.getRunningTasks(1).get(0).topActivity
                    .getPackageName();
        }

        // There is a limit to the tag length of 23.
        packageName = packageName
                .substring(0, packageName.length() > 22 ? 22 : packageName.length());

    }catch (Exception ex){
    }

    if (packageName.isEmpty()){
        packageName = pContext.getPackageName();
    }

    return packageName;
}




public static void toCatch(Activity activity){

    Thread.setDefaultUncaughtExceptionHandler(getINSTANCE(activity));
}







public static void logError(String message){

    if (message.isEmpty()){

        return;
    }

    logError(new Throwable(message.trim()));
}




public static void logError(Throwable exception){

    try{

        logCrash(exception);

    }catch (Exception e){

        Log.e(mPackageName, e.getMessage());
    }
}



// Return the last error message
public static String getErrorMessage(){

    return mErrorMessage;
}




public static void setErrorMessage(String errMsg){

    mErrorMessage = errMsg;
}



// Return the last crash information
public static ApplicationErrorReport.CrashInfo crashInfo(){

    return mCrashInfo;
}




private static String getAppLabel(Context pContext){

    PackageManager lPackageManager = pContext.getPackageManager();

    ApplicationInfo lApplicationInfo = null;

    try{

        lApplicationInfo = lPackageManager
                .getApplicationInfo(pContext.getApplicationInfo().packageName, 0);

    }catch (final PackageManager.NameNotFoundException e){
    }

    return (String) (lApplicationInfo != null ? lPackageManager
            .getApplicationLabel(lApplicationInfo) : "Unknown");
}



public static boolean inDebugger(){

    //  If in Debugger Environment
    boolean debugging = Debug.isDebuggerConnected();

    return debugging;
}


@NonNull
private static String errorMsg(Throwable exception, String exceptError){

    if (!exceptError.contains("error")){

        mReportBuilder.append(reportError(exception));
    }

    if (!exceptError.contains("callstack")){

        mReportBuilder.append(reportCallStack(exception));
    }

    if (!exceptError.contains("deviceinfo")){

        mReportBuilder.append(reportDeviceInfo());
    }

    if (!exceptError.contains("firmware")){

        mReportBuilder.append(reportFirmware());
    }

    return mReportBuilder.toString();
}




private static String reportError(Throwable exception){

    mCrashInfo = new ApplicationErrorReport.CrashInfo(exception);

    if (mCrashInfo.exceptionMessage == null){

        mErrorMessage = "<unknown error>";
    }else{

        mErrorMessage = mCrashInfo.exceptionMessage
                .replace(": " + mCrashInfo.exceptionClassName, "");
    }

    String throwFile = mCrashInfo.throwFileName == null ? "<unknown file>"
                                                        : mCrashInfo.throwFileName;

    return "\n************ " + mCrashInfo.exceptionClassName + " ************\n"
            + mErrorMessage + LINE_SEPARATOR
            + "\n File: " + throwFile
            + "\n Method: " + mCrashInfo.throwMethodName + "()"
            + "\n Line No.: " + Integer.toString(mCrashInfo.throwLineNumber)
            + LINE_SEPARATOR;
    //          + "Class: " + crashInfo.throwClassName + LINE_SEPARATOR
}




private static String reportCallStack(Throwable exception){

    StringWriter stackTrace = new StringWriter();

    exception.printStackTrace(new PrintWriter(stackTrace));

    String callStack = stackTrace.toString();

    String errMsg = exception.toString();

    return "\n************ CALLSTACK ************\n"
            + callStack.replace(errMsg, "")
            + LINE_SEPARATOR;
}




private static String reportDeviceInfo(){

    return "\n************ DEVICE INFORMATION ***********\n"
            + "Brand: "
            + Build.BRAND
            + LINE_SEPARATOR
            + "Device: "
            + Build.DEVICE
            + LINE_SEPARATOR
            + "Model: "
            + Build.MODEL
            + LINE_SEPARATOR
            + "Id: "
            + Build.ID
            + LINE_SEPARATOR
            + "Product: "
            + Build.PRODUCT
            + LINE_SEPARATOR;
}




private static String reportFirmware(){

    return "\n************ FIRMWARE ************\n"
            + "SDK: "
            + Build.VERSION.SDK_INT
            + LINE_SEPARATOR
            + "Release: "
            + Build.VERSION.RELEASE
            + LINE_SEPARATOR
            + "Incremental: "
            + Build.VERSION.INCREMENTAL
            + LINE_SEPARATOR;
}




// Empty the report as it is begin re-populated.
private static void reportEmptied(){

    // No need to empty
    if (mReportBuilder.length() == 0){

        return;
    }

    mReportBuilder.setLength(0);

    mReportBuilder.trimToSize();
}




@Override
public void uncaughtException(Thread thread, Throwable exception){

    // Don't re-enter -- avoid infinite loops if crash-reporting crashes.
    if (mCrashing) return;

    mCrashing = true;

    catchException(thread, exception);

    defaultExceptionHandler(thread, exception);
}




public String catchException(Thread thread, Throwable exception){

    String errorMsg = "";

    try{

        errorMsg = logCrash(exception);

    }catch (Exception ex){

        Log.e(mPackageName, ex.getMessage());
    }

    return errorMsg;
}




public static void defaultExceptionHandler(Thread thread, Throwable exception){

    try{

        // Execute the old handler.
        if (mOldHandler != null){

            mOldHandler.uncaughtException(thread, exception);
        }

    }catch (Exception ex){

        Log.e(mPackageName, ex.getMessage());
    }
}




public static String logCrash(Throwable exception){

    return errorMsg(exception, "deviceinfo firmware");
}




public void onDestroy(){

    mErrorHandler = null;
}

// Prevents infinite loops.
private static volatile boolean mCrashing = false;

private static final StringBuilder mReportBuilder = new StringBuilder();

private static final String LINE_SEPARATOR = "\n";

private static final UncaughtExceptionHandler mOldHandler = Thread
        .getDefaultUncaughtExceptionHandler();

private static ErrorHandler mErrorHandler;

private static String mPackageName;

private static ApplicationErrorReport.CrashInfo mCrashInfo;

private static String mErrorMessage = "";
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM