1. What does Crash mean
- Crash is the abnormal Crash of the APP code, which leads to the flash withdrawal of the APP. Maybe everything is normal when we test during the development, but when the number of online users increases, there are all kinds of computers, and more or less Crash will occur.
- When the App crashes, we should record the problem in time and save it in a file. When the App is started next time, we will upload it to the server and analyze the error log to correct the problem.
- Android has Java layer Crash, and Native layer Carsh, this time to learn how to get Java layer Crash.
2. Java layer Crash
- In Java, Thread defines an interface: UncaughtExceptionHandler, which is used to handle the termination of the Thread due to uncaught exceptions. However, try/catch errors cannot be caught.
- When our application crash will go UncaughtExceptionHandler. UncaughtException, in this method can obtain the information of abnormal, Through the Thread. SetDefaultUncaughtExceptionHandler the method to set the default Thread exception handler.
- Call uncaughtException(t, e) again after rewriting uncaughtException(t, e), otherwise the screen will go blank and APP will wait there.
- Carsh files can be saved and uploaded to the server, or uploaded next time you open the App.
2.1 Saving Crash Information
public class TestCrashHandler implements Thread.UncaughtExceptionHandler {
//crash storage folder, /Android/data/ package name /files/crash_info/ directory
private static final String CRASH_FILES = "crash_info";
//crash file suffix
private static final String CRASH_FILE_NAME = "_crash.txt";
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static Context mContext;
private static Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
private SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
public static void init(Context context) {
mContext = context.getApplicationContext();
uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new TestCrashHandler());
}
@Override
public void uncaughtException(@NonNull @NotNull Thread t, @NonNull @NotNull Throwable e) {
saveCrash(t, e);
}
/** * Save the Crash information **@param t
* @param e
*/
private void saveCrash(@NonNull @NotNull Thread t, @NonNull @NotNull Throwable e) {
// Create a folder /Android/data/ package name /files/crash_info/
File dir = mContext.getExternalFilesDir(CRASH_FILES);
if(! dir.exists()) { dir.mkdirs(); }/ / Crash time
String time = dateFormat.format(System.currentTimeMillis());
File file = new File(dir, time + CRASH_FILE_NAME);
PrintWriter printWriter = null;
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file);
printWriter = new PrintWriter(fileWriter);
// Exception time
printWriter.write("Crash_Time : " + time + "\n");
// Cell phone info
printWriter.write(phoneInfo());
// Thread information
printWriter.write("Thread : " + t.getName() + "\n");
// Exception information
printWriter.write("Exception : " );
e.printStackTrace( printWriter);
} catch (IOException | PackageManager.NameNotFoundException ioException) {
ioException.printStackTrace();
} finally {
try {
if(printWriter ! =null) {
printWriter.flush();
printWriter.close();
}
if(fileWriter ! =null) { fileWriter.flush(); fileWriter.close(); }}catch (IOException ioException) {
ioException.printStackTrace();
}
// If you do not write, the APP may display a blank screen without flashing back, i.e. no processing
if(uncaughtExceptionHandler ! =null) { uncaughtExceptionHandler.uncaughtException(t, e); }}}/** * Get App information, phone information, and other required information **@return
* @throws PackageManager.NameNotFoundException
*/
private String phoneInfo(a) throws PackageManager.NameNotFoundException {
StringBuilder stringBuilder = new StringBuilder();
PackageManager pkm = mContext.getPackageManager();
PackageInfo packageInfo = pkm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
/ / App versions
stringBuilder.append("App_VersionName : ");
stringBuilder.append(packageInfo.versionName);
stringBuilder.append("\n");
stringBuilder.append("App_VersionCode : ");
stringBuilder.append(packageInfo.versionCode);
stringBuilder.append("\n");
/ / Android version number
stringBuilder.append("Android_Version : ");
stringBuilder.append(Build.VERSION.RELEASE);
stringBuilder.append("\n");
stringBuilder.append("Android_VersionCode : ");
stringBuilder.append(Build.VERSION.SDK_INT);
stringBuilder.append("\n");
// Phone manufacturer
stringBuilder.append("Vendor : ");
stringBuilder.append(Build.MANUFACTURER);
stringBuilder.append("\n");
// Phone type
stringBuilder.append("Phone_Model : ");
stringBuilder.append(Build.MODEL);
stringBuilder.append("\n");
/ / CPU architecture
stringBuilder.append("CPU : ");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
stringBuilder.append(Arrays.toString(Build.SUPPORTED_ABIS));
} else {
stringBuilder.append(Build.CPU_ABI);
}
stringBuilder.append("\n");
returnstringBuilder.toString(); }}Copy the code
2.2 test
public class CrashTestReport {
public static void init(Context application){
TestCrashHandler.init(application);
}
/** * RuntimeException */
public static void test1(a){
int i = 1/0;
}
/** * StackOverflowError */
public static void test2(a){ test2(); }}Copy the code
2.3 Crash information in the file
- Test1 method test result, RuntimeException.
Crash_Time : 2021-06-04 22:43:56
App_VersionName : 1.0
App_VersionCode : 1
Android_Version : 10
Android_VersionCode : 29
Vendor : HUAWEI
Phone_Model : VOG-AL00
CPU : [arm64-v8a, armeabi-v7a, armeabi]
Thread : main
Exception : java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bao.myapplication/com.bao.myapplication.MainActivity}: java.lang.ArithmeticException: divide by zero
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3898)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4081)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2462)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Caused by: java.lang.ArithmeticException: divide by zero
at com.bao.myapplication.carsh.CrashTestReport.test1(CrashTestReport.java:11)
at com.bao.myapplication.MainActivity.onCreate(MainActivity.kt:79)
at android.app.Activity.performCreate(Activity.java:8121)
at android.app.Activity.performCreate(Activity.java:8109)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3871)...11 more
Copy the code
- Test2: StackOverflowError
Crash_Time : 2021-06-05 00:49:39
App_VersionName : 1.0
App_VersionCode : 1
Android_Version : 10
Android_VersionCode : 29
Vendor : HUAWEI
Phone_Model : VOG-AL00
CPU : [arm64-v8a, armeabi-v7a, armeabi]
Thread : main
Exception : java.lang.StackOverflowError: stack size 8192KB
at com.bao.myapplication.carsh.CrashTestReport.test2(CrashTestReport.java:15)
at com.bao.myapplication.carsh.CrashTestReport.test2(CrashTestReport.java:15)
at com.bao.myapplication.carsh.CrashTestReport.test2(CrashTestReport.java:15)
.
.
at com.bao.myapplication.carsh.CrashTestReport.test2(CrashTestReport.java:15)
at com.bao.myapplication.carsh.CrashTestReport.test2(CrashTestReport.java:15)
at com.bao.myapplication.MainActivity.onCreate(MainActivity.kt:79)
at android.app.Activity.performCreate(Activity.java:8121)
at android.app.Activity.performCreate(Activity.java:8109)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3871)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4081)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2462)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
Copy the code