The biggest headache for programmers is bug and debug. This debug lasted 20 days, and I made a failover. Tired, because of Android compatibility, different mobile phones may have different bugs, and it is difficult to reproduce, So I went online and found a similar error log to save it to the file and then upload it to the server, the source code is also shared. I did not add the code uploaded to the server. I believe everyone has ready-made code.
First, let's talk about the principle. Like the custom exception capture of JavaEE, the error is always thrown up and then processed at the top. The Exception Message can be obtained and saved.
The exception capture class is as follows:
Copy codeThe Code is as follows :/**
* @ Author Stay
* The exception is caught in the Application and uploaded when the file is saved to the next open attempt
*/
Public class CrashHandler implements UncaughtExceptionHandler {
/** Whether to enable log output and enable it in Debug status,
* Shut down in the Release status to prompt Program Performance
**/
Public static final boolean DEBUG = true;
/** Default UncaughtException processing class */
Private Thread. UncaughtExceptionHandler mDefaultHandler;
/** CrashHandler instance */
Private static CrashHandler INSTANCE;
/** Context object of the Program */
// Private Context mContext;
/** Ensure that there is only one CrashHandler instance */
Private CrashHandler (){}
/** Obtain the CrashHandler instance. Singleton mode */
Public static CrashHandler getInstance (){
If (INSTANCE = null ){
INSTANCE = new CrashHandler ();
}
Return INSTANCE;
}
/**
* Initialize and register the Context object,
* Obtain the default UncaughtException processor,
* Set the CrashHandler as the default processor of the program.
*
* @ Param ctx
*/
Public void init (Context ctx ){
// MContext = ctx;
MDefaultHandler = Thread. getDefaultUncaughtExceptionHandler ();
Thread. setDefaultUncaughtExceptionHandler (this );
}
/**
* When UncaughtException occurs, it is transferred to this function for processing.
*/
@ Override
Public void uncaughtException (Thread thread, Throwable ex ){
If (! HandleException (ex) & mDefaultHandler! = Null ){
// If the user does not handle the exception, the system's default exception processor will handle the exception.
MDefaultHandler. uncaughtException (thread, ex );
} Else {// If the exception is handled by yourself, the error dialog box is not displayed, and you need to exit the app manually.
Try {
Thread. sleep (3000 );
} Catch (InterruptedException e ){
}
Android. OS. Process. killProcess (android. OS. Process. myPid ());
System. exit (10 );
}
}
/**
* Custom error handling, collecting error information
* Sending error reports and other operations are completed here.
* Developers can customize the exception handling logic based on their own situations.
* @ Return
* True indicates that the exception is handled and no exception is thrown up,
* False indicates that the exception is not handled (the log information can be stored) and then handed over to the upper layer (here the Exception Processing of the system is implemented) for processing,
* Simply put, true does not bring up the error prompt box, and false does.
*/
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 exception information
New Thread (){
@ Override
Public void run (){
Logoff. prepare ();
// Toast. makeText (mContext, "program error:" + message, Toast. LENGTH_LONG). show ();
// You can create only one file, append all the files in it, and then send them. This leads to duplicate information, which is not recommended by individuals.
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 ){
}
Logoff. loop ();
}
}. Start ();
Return false;
}
// TODO uses HTTP Post to send the Error Report to the server.
// Private void postReport (File file ){
// You can also send the version of the app, the model of the mobile phone, and other information to the server during upload,
// Android compatibility is well known, so possible errors may not be reported on every mobile phone, but it is better to debug it in a targeted manner.
//}
}
Register ExceptionHandler in Application onCreate, which can be captured after the program throws an exception.Copy codeThe Code is as follows: public class App extends Application {
@ Override
Public void onCreate (){
Super. onCreate ();
CrashHandler crashHandler = CrashHandler. getInstance ();
// Register crashHandler
CrashHandler. init (getApplicationContext ());
}
}
? Public class LogActivity extends Activity {
@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );
Try {// create a bug
File file = new File (Environment. getExternalStorageState (), "crash. bin ");
FileInputStream FCM = new FileInputStream (file );
Byte [] buffer = new byte [1024];
FS. read (buffer );
} Catch (Exception e ){
// No exception can be thrown up here. If you want to save the log information, a runtime exception is thrown,
// Let the Custom handler capture and save the file and upload it in a unified manner
Throw new RuntimeException (e );
}
}
}
NOTE: If no throw is triggered after a catch operation, it is handled by yourself by default. ExceptionHandler will not catch exceptions.
To share a Log encapsulation class, you only need to set the DEBUG value here so that the console can print the log
Copy codeThe Code is as follows: 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 );
}
}