[英]Thread.setDefaultUncaughtExceptionHandler for Errors
[英]How to use Thread.setDefaultUncaughtExceptionHandler?
如何使用 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.