This is the 8th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Application of abnormal

Bugs are a daily part of development, and bugs are mostly crashes. When a serious exception occurs during application running, Crash will occur, such as null pointer exception or memory overflow. When an exception occurs, the system kills the running program and terminates the process.

Developers can use the development Log to view crash logs and fix problems during daily development. However, the developer cannot directly perceive and obtain crash information when the online environment and test encounter crash and the application flashes back and the program stops running. This is an extremely unfriendly situation for developers, having Crash problems and not knowing how to fix the Crash.

Fortunately, Android provides a way to handle exceptions. Java provides Thread. UncaughtExceptionHandler processor, a global exception handling in the Android environment also can be used.

Thread.UncaughtExceptionHandler

Thread. UncaughtExceptionHandler is an interface method and processing in the program has not been captured exception information.

However, a try-catch added by the developer will be intercepted by the developer and will not be collected by the exception catcher.

@FunctionalInterface
public interface UncaughtExceptionHandler {
    /**
     * Method invoked when the given thread terminates due to the
     * given uncaught exception.
     * <p>Any exception thrown by this method will be ignored by the
     * Java Virtual Machine.
     * @param t the thread
     * @param e the exception
     */
    void uncaughtException(Thread t, Throwable e);
}
Copy the code

Implementation method

Custom exception fetching classes

public class CrashHandler implements Thread.UncaughtExceptionHandler{
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        // Global catch exception is here}}Copy the code

Initialization method that first gets the current thread’s exception catcher and then sets the custom exception catcher class as thread exception catcher so that global exceptions are caught by the custom class.

Thread.UncaughtExceptionHandler mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
Copy the code

Information collection

The information collected is implemented in the callback method uncaughtException, and the error Throwable is read to transfer the text content to a local file or upload it to the server.

  • Error stack information
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
Throwable cause = ex;
while(cause ! =null){
    cause.printStackTrach(printWriter);
    cause = cause.getCause();
}
final String stacktraceAsString = result.toString();
printWriter.close();
Copy the code
  • Error thread information
StringBuilder result = new StringBuilder();
if(thread! =null){     
    result.append("id=").append(thread.getId()).append("\n");      
    result.append("name=").append(thread.getName()).append("\n");   
    result.append("priority=").append(thread.getPriority()).append("\n");
       if(t.getThreadGroup()! =null)){ 
           result.append("groupName=").append(thread.getThreadGroup().getName()).append("\n"); }}return result.toString();
}
Copy the code
  • System information

In addition to the exception information, some additional information is needed to help the developer better identify the cause of the problem. For example, some model adaptation problems or errors only occur in low-end machines. Therefore, you can report additional information about the application running system when exceptions occur. For details about how to obtain basic device information, see # Obtaining Basic Android Device Information

  • memory

In addition, the ability to obtain memory usage information when exceptions occur also improves the ability to locate problems.

public static String collectMemInfo(a){
        final StringBuilder meminfo = new StringBuilder();
        BufferedReader bufferedReader = null;
        try{
            final List<String commandLine = new ArrayList<>();
            commandLine.add("dumpsys");
            commandLine.add("meminfo");
            commandLine.add(Integer.toString(android.os.Process.myPid()));
            final Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[commandLine.size()]));
            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()), DEFAULT_BUFFER_SIZE_IN_BYTES);
            while(true) {final String line = bufferedReader.readLine();
                if(line == null)break;
                meminfo.append(line);
                meminfo.append("\n"); }}catch(Exception e){}
       try{
           if(null! =bufferedReader){ bufferedReader.close(); }catch(Exception e){}
       }
       return meminfo.toString();
    }
Copy the code

Native exception

Native exception for Android applications using Thread. UncaughtExceptionHandler cannot be captured. C++ exceptions are usually caused by wild Pointers or memory read out of bounds. You can see the error log in LogCat. However, it is not particularly easy to get Native layer exceptions easily and quickly, unlike the Android source code which provides the exception catcher to get directly.

  1. The known method is refactoringLogCatLog information to fetch stack information, by opening a new process service to fetchLogCatInformation foundNativeException and save.
  2. Integrated Open Source librariesxCrashException information is captured. Procedure
  3. To be added.