Android capture crash exception, Android capture crash
The biggest headache in development is the sudden explosion of applications and the jump back to the desktop. In addition, we often do not know when this situation will occur. In the application debugging phase, we can also check the errors in the logs of the debugging tool. However, when you use it in normal times, it makes you cry.
Today, we will focus on how to capture the appearance of the system.UncheckedException. What isUncheckedExceptionIn other words, a non-checked exception cannot be caught by try-catch.
Let's start with Exception. There are two types of exceptions: CheckedException and UncheckedException. The main difference between the two types of exceptions is that CheckedException must be captured by try... catch..., while UncheckedException does not need to be captured. Generally, UncheckedException is also called RuntimeException. Warning java states that the checkkedexception can be used for recoverable conditions, and the runtime exception (RuntimeException) can be used for program errors (unrecoverable by implication, leading to a big mistake ). Our common runtimeexpiton include IllegalArgumentException, IllegalStateException, NullPointerException, IndexOutOfBoundsException, and so on. For those CheckedException, the exception caught by try... catch... is always CheckedException. IOException and its subclass in the io package are all CheckedException.
1. Use UncaughtExceptionHandler to capture unchecked exceptions
UncaughtException processing class. When an Uncaught exception occurs in a program, this class takes over the program and records the error report.
Run the Code directly.
1 import java. io. file; 2 import java. io. fileOutputStream; 3 import java. io. printWriter; 4 import java. io. stringWriter; 5 import java. io. writer; 6 import java. lang. thread. uncaughtExceptionHandler; 7 import java. lang. reflect. field; 8 import java. text. dateFormat; 9 import java. text. simpleDateFormat; 10 import java. util. date; 11 import java. util. hashMap; 12 import java. util. locale; 13 import java. util. Map; 14 import java. util. map. entry; 15 import java. util. regex. matcher; 16 import java. util. regex. pattern; 17 18 import android. annotation. suppressLint; 19 import android. content. context; 20 import android. content. pm. packageInfo; 21 import android. content. pm. packageManager; 22 import android. content. pm. packageManager. nameNotFoundException; 23 import android. OS. build; 24 import android. OS. environmen T; 25 import android. OS. logoff; 26 import android. util. log; 27 import android. widget. toast; 28 29/** 30 * UncaughtException processing class. When an Uncaught exception occurs in a program, this class is used to take over the program and send an error report. 31*32 * @ author user 33*34 */35 @ SuppressLint ("SdCardPath") 36 public class CrashHandler implements UncaughtExceptionHandler {37 38 public static final String TAG = "TEST "; 39 40 // CrashHandler instance 41 private static CrashHandle R INSTANCE = new CrashHandler (); 42 43 // Context object of the program 44 private Context mContext; 45 46 // the system's default UncaughtException processing class 47 private Thread. uncaughtExceptionHandler mDefaultHandler; 48 49 // used to store device information and exception information 50 private Map <String, String> infos = new HashMap <String, String> (); 51 52 // used to display information in Toast 53 private static String error = "program error, amount, no, I should say, the server is being maintained. Please try again later "; 54 55 private static final Map <Stri Ng, String> regexMap = new HashMap <String, String> (); 56 57 // used to format a date, 58 private DateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd-HH-mm-ss", 59 Locale. CHINA); 60 61/** ensure that there is only one CrashHandler instance */62 private CrashHandler () {63 // 64} 65 66/** get the CrashHandler instance, singleton mode */67 public static CrashHandler getInstance () {68 initMap (); 69 return INSTANCE; 70} 71 72/** 73 * initialize 74*75 * @ param context 76 */77 public void init (Context context) {78 mContext = context; 79 80 // obtain the default UncaughtException processor 81 mDefaultHandler = Thread. getDefaultUncaughtExceptionHandler (); 82 83 // sets the CrashHandler as the program's default processor 84 Thread. setDefaultUncaughtExceptionHandler (this); 85 Log. d ("TEST", "Crash: init "); 86} 87 88/** 89 * When UncaughtException occurs, it will be transferred to this function to process 90 */91 @ Override 92 public void UncaughtException (Thread thread, Throwable ex) {93 if (! HandleException (ex) & mDefaultHandler! = Null) {94 // if the user does not handle it, the system's default exception processor will handle 95 mDefaultHandler. uncaughtException (thread, ex); 96 Log. d ("TEST", "defalut"); 97} else {98 try {99 Thread. sleep (3000); 100} catch (InterruptedException e) {101 Log. e (TAG, "error:", e); 102} 103 // exit program 104 android. OS. process. killProcess (android. OS. process. myPid (); 105 // mDefaultHandler. uncaughtException (thread, ex); 106 System. exit (1); 107} 108} 109 110 /* * 111 * custom error handling, collection of error information, and sending of error reports are all completed here. 112*113 * @ param ex114 * @ return true: If the exception information is processed; otherwise, false115 */116 private boolean handleException (Throwable ex) {117 if (ex = null) {118 return false; 119} 120 121 // collect device parameter information 122 // collectDeviceInfo (mContext); 123 // Save the log file 124 saveCrashInfo2File (ex ); 125 // use Toast to display exception information 126 new Thread () {127 @ Override128 public void run () {129 logoff. prepare (); 130 Toast. m AkeText (mContext, error, Toast. LENGTH_LONG ). show (); 131 logoff. loop (); 132} 133 }. start (); 134 return true; 135} 136 137/** 138 * collect device parameter information 139*140 * @ param ctx141 */142 public void collectDeviceInfo (Context ctx) {143 try {144 PackageManager pm = ctx. getPackageManager (); 145 PackageInfo pi = pm. getPackageInfo (ctx. getPackageName (), 146 PackageManager. GET_ACTIVITIES); 147 148 if (pi! = Null) {149 String versionName = pi. versionName = null? "Null" 150: pi. versionName; 151 String versionCode = pi. versionCode + ""; 152 infos. put ("versionName", versionName); 153 infos. put ("versionCode", versionCode); 154} 155} catch (NameNotFoundException e) {156 Log. e (TAG, "an error occured when collect package info", e); 157} 158 159 Field [] fields = Build. class. getDeclaredFields (); 160 for (Field field: fields) {161 try {162 field. setAccessible (true); 163 Infos. put (field. getName (), field. get (null ). toString (); 164 Log. d (TAG, field. getName () + ":" + field. get (null); 165} catch (Exception e) {166 Log. e (TAG, "an error occured when collect crash info", e ); 167} 168} 169} 170 171/** 172 * Save the error message to the file * 173*174 * @ param ex175 * @ return returns the file name, transfers files to the server 176 */177 private String saveCrashInfo2File (Throwable ex) {178 StringBuffer sb = getTraceInfo (ex); 17 9 Writer writer = new StringWriter (); 180 PrintWriter printWriter = new PrintWriter (writer); 181 ex. printStackTrace (printWriter); 182 Throwable cause = ex. getCause (); 183 while (cause! = Null) {184 cause. printStackTrace (printWriter); 185 cause = cause. getCause (); 186} 187 printWriter. close (); 188 189 String result = writer. toString (); 190 sb. append (result); 191 try {192 long timestamp = System. currentTimeMillis (); 193 String time = formatter. format (new Date (); 194 String fileName = "crash-" + time + "-" + timestamp + ". log "; 195 196 if (Environment. getExternalStorageState (). equals (197 E Environment ronment. MEDIA_MOUNTED) {198 String path = Environment. getExternalStorageDirectory () 199 + "/crash/"; 200 File dir = new File (path); 201 if (! Dir. exists () {202 dir. mkdirs (); 203} 204 FileOutputStream fos = new FileOutputStream (path + fileName); 205 fos. write (sb. toString (). getBytes (); 206 fos. close (); 207} 208 209 return fileName; 210} catch (Exception e) {211 Log. e (TAG, "an error occured while writing file... ", e); 212} 213 214 return null; 215} 216 217/** 218 * sorting exception information 219 * @ param e220 * @ return221 */222 public static StringBuffer getTraceIn Fo (Throwable e) {223 StringBuffer sb = new StringBuffer (); 224 225 Throwable ex = e. getCause () = null? E: e. getCause (); 226 StackTraceElement [] stacks = ex. getStackTrace (); 227 for (int I = 0; I <stacks. length; I ++) {228 if (I = 0) {229 setError (ex. toString (); 230} 231 sb. append ("class :"). append (stacks [I]. getClassName () 232. append ("; method :"). append (stacks [I]. getMethodName () 233. append ("; line :"). append (stacks [I]. getLineNumber () 234. append ("; Exception :"). append (ex. toString () + "\ n"); 235} 236 Log. d (TAG, sb. toString (); 237 return sb; 238} 239 240/** 241 * incorrect prompt 242 * @ param e243 */244 public static void setError (String e) {245 Pattern pattern; 246 Matcher matcher; 247 for (Entry <String, String> m: regexMap. entrySet () {248 Log. d (TAG, e + "key:" + m. getKey () + "; value:" + m. getValue (); 249 pattern = Pattern. compile (m. getKey (); 250 matcher = pattern. matcher (e); 251 if (matcher. matches ()) {252 error = m. getValue (); 253 break; 254} 255} 256 257 258/** 259 * incorrect initialization prompt 260 */261 private static void initMap () {262/Java. lang. nullPointerException263 // java. lang. classNotFoundException264 // java. lang. arithmeticException265 // java. lang. arrayIndexOutOfBoundsException266 // java. lang. illegalArgumentException267 // java. lang. illegalAccessException268 // SecturityException269 // NumberForma TException270 // OutOfMemoryError 271 // StackOverflowError 272 // RuntimeException 273 regexMap. put (". * NullPointerException. *", "Hey, Miss ~ Boom! "); 274 regexMap. put (". * ClassNotFoundException. * "," Are you sure you can find it? "); 275 regexMap. put (". * ArithmeticException. * "," I guess your mathematics is taught by a PE Instructor, right? "); 276 regexMap. put (". * ArrayIndexOutOfBoundsException. * "," Well, no lower limit = No node operation, please do not talk to me "); 277 regexMap. put (". * IllegalArgumentException. * "," your birth is an error. "); 278 regexMap. put (". * IllegalAccessException. * "," Sorry, your credit card account has been frozen and you are not authorized to pay "); 279 regexMap. put (". * SecturityException. * "," Death comes soon "); 280 regexMap. put (". * NumberFormatException. * "," do you want to change your image? Go to Thailand, pack you satisfied "); 281 regexMap. put (". * OutOfMemoryError. * "," Maybe you should lose weight "); 282 regexMap. put (". * StackOverflowError. * "," ah, ah, I can't help it! "); 283 regexMap. put (". * RuntimeException. * "," your life goes wrong. Come back. "); 284 285} 286}
2. Create an Application for global monitoring
import android.app.Application;public class CrashApplication extends Application { @Override public void onCreate() { super.onCreate(); CrashHandler crashHandler = CrashHandler.getInstance(); crashHandler.init(getApplicationContext()); }}
Add registration information to the configuration file.
<application android:name=".CrashApplication" ... />
And Permissions
<!--uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
The error log has not been added to the network server. If this feature is added, you can get real-time error logs for users to use and timely report errors of different models, it brings great convenience to our developers for their later maintenance.