Capture the details sent to the server based on Android error messages

  • 2020-05-10 18:51:47
  • OfStack

The biggest headaches for programmers are bug and debug. This time debug lasted 20 days and I was exhausted. Tired, because of the compatibility of Android, different phones will have different bug out, and it is difficult to reproduce, so I searched the Internet similar to save log error to the file and then uploaded to the server, now the source is also Shared out. I did not add the code uploaded to the server. I'm sure you have the code out there.

First, just like JavaEE's custom exception catch 1, throw error 1 straight up and then handle it at the top level. Here you can get Exception Message and save it
Exception catching classes are as follows:

/** 
 * @author Stay 
 *       in Application knee 1 Catch the exception, save it to a file and upload it the next time you open it  
 */
public class CrashHandler implements UncaughtExceptionHandler {   
    /**  Whether log output is turned on or not , in Debug State on ,  
     *  in Release Closed under state to indicate program performance   
     * */  
    public static final boolean DEBUG = true;   
    /**  System default UncaughtException Processing class  */  
    private Thread.UncaughtExceptionHandler mDefaultHandler;   
    /** CrashHandler The instance  */  
    private static CrashHandler INSTANCE;   
    /**  Of the program Context object  */  
//    private Context mContext;   
    /**  Ensure that only 1 a CrashHandler The instance  */  
    private CrashHandler() {}   
    /**  To obtain CrashHandler The instance  , The singleton pattern */  
    public static CrashHandler getInstance() {   
        if (INSTANCE == null) {   
            INSTANCE = new CrashHandler();   
        }   
        return INSTANCE;   
    }   

    /**  
     *  Initialize the , registered Context object ,  
     *  Gets the system default UncaughtException The processor ,  
     *  Set the CrashHandler Is the program's default processor   
     *   
     * @param ctx  
     */  
    public void init(Context ctx) {   
//        mContext = ctx;   
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();   
        Thread.setDefaultUncaughtExceptionHandler(this);   
    }   

    /**  
     *  when UncaughtException When that happens, it's passed over to this function   
     */  
    @Override  
    public void uncaughtException(Thread thread, Throwable ex) {   
        if (!handleException(ex) && mDefaultHandler != null) {   
            // If the user does not handle it, let the system's default exception handler handle it    
            mDefaultHandler.uncaughtException(thread, ex);   
        } else {  // If you handle the exception yourself, the error dialog will not pop up and you will need to exit manually app 
            try {   
                Thread.sleep(3000);   
            } catch (InterruptedException e) {   
            }   
            android.os.Process.killProcess(android.os.Process.myPid());   
            System.exit(10);   
        }   
    }   

    /**  
     *  Custom error handling , Collecting error information   
     *  Operations such as sending error reports are done here .  
     *  Developers can customize the exception handling logic to their own circumstances   
     * @return  
     * true Is to handle the exception and no longer throw the exception up,  
     * false Represents not handling the exception ( Can use the log Information is stored ) And then give it to the top ( This brings us to the exception handling of the system ) To deal with,  
     *  In a nutshell true It doesn't pop up that error box, false Will pop up  
     */  
    private boolean handleException(final Throwable ex) {   
        if (ex == null) {   
            return false;   
        }   
//        final String msg = ex.getLocalizedMessage();   
        final StackTraceElement[] stack = ex.getStackTrace(); 
        final String message = ex.getMessage(); 
        // use Toast To display the exception information    
        new Thread() {   
            @Override  
            public void run() {   
                Looper.prepare();   
//                Toast.makeText(mContext, " Program error :" + message, Toast.LENGTH_LONG).show();   
//                 You can just create 1 A file, all later into it append Then send it so that there will be duplicate messages that are not personally recommended  
                String fileName = "crash-" + System.currentTimeMillis()  + ".log";   
                File file = new File(Environment.getExternalStorageDirectory(), fileName); 
                try { 
                    FileOutputStream fos = new FileOutputStream(file,true); 
                    fos.write(message.getBytes()); 
                    for (int i = 0; i < stack.length; i++) { 
                        fos.write(stack[i].toString().getBytes()); 
                    } 
                    fos.flush(); 
                    fos.close(); 
                } catch (Exception e) { 
                } 
                Looper.loop();   
            }   

        }.start();   
        return false;   
    }   

    // TODO  use HTTP Post  Send an error report to the server    I won't repeat it here  
//    private void postReport(File file) {   
//       It can also be uploaded app the version , the model of the phone and other information 1 And send it to the server,  
//      Android Compatibility is well known, so errors may not be reported on every phone, or targeted to go debug better  
//    }   
}

ExceptionHandler is registered at Application onCreate and can be caught as soon as the program throws an exception.

public class App extends Application{ 
        @Override  
        public void onCreate() {   
            super.onCreate();   
            CrashHandler crashHandler = CrashHandler.getInstance();   
            // registered crashHandler   
            crashHandler.init(getApplicationContext());   
        }   
} 
?public class LogActivity extends Activity { 
    @Override
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        try {// manufacturing bug 
            File file = new File(Environment.getExternalStorageState() ,"crash.bin"); 
            FileInputStream fis = new FileInputStream(file); 
            byte[] buffer = new byte[1024]; 
            fis.read(buffer); 
        } catch (Exception e) { 
            // You can't throw an exception up here, if you want to log The information is saved and thrown runtime Abnormal,  
//           Make it custom handler To capture 1 Save the file and upload it  
            throw new RuntimeException(e); 
        } 
    } 
} 

Note that if catch is not throw by default, ExceptionHandler will not catch exceptions.
Share one more Log wrapper class, and simply set the value of DEBUG here to make the console print out log or not

public class DebugUtil { 
    public static final String TAG = "ICON"; 
    public static final boolean DEBUG = true; 

    public static void toast(Context context,String content){ 
        Toast.makeText(context, content, Toast.LENGTH_SHORT).show(); 
    } 

    public static void debug(String tag,String msg){ 
        if (DEBUG) { 
            Log.d(tag, msg); 
        } 
    } 

    public static void debug(String msg){ 
        if (DEBUG) { 
            Log.d(TAG, msg); 
        } 
    } 

    public static void error(String tag,String error){ 
        Log.e(tag, error); 
    } 

    public static void error(String error){ 
        Log.e(TAG, error); 
    } 
}


Related articles: