Skip to content

Commit 23d0394

Browse files
committed
see 09/30 log
1 parent 3757dd6 commit 23d0394

File tree

1 file changed

+126
-50
lines changed

1 file changed

+126
-50
lines changed

utilcode/src/main/java/com/blankj/utilcode/utils/CrashUtils.java

+126-50
Original file line numberDiff line numberDiff line change
@@ -2,83 +2,159 @@
22

33
import android.content.Context;
44
import android.content.pm.PackageInfo;
5-
import android.os.Looper;
5+
import android.os.Build;
6+
import android.os.Environment;
7+
8+
import java.io.File;
9+
import java.io.FileWriter;
10+
import java.io.IOException;
11+
import java.io.PrintWriter;
12+
import java.lang.Thread.UncaughtExceptionHandler;
613

714
/**
815
* <pre>
916
* author: Blankj
1017
* blog : http://blankj.com
1118
* time : 2016/9/27
12-
* desc :
19+
* desc : 崩溃相关工具类
1320
* </pre>
1421
*/
1522
public class CrashUtils implements Thread.UncaughtExceptionHandler {
1623

17-
private Thread.UncaughtExceptionHandler mDefaultHandler;
18-
private static CrashUtils INSTANCE;
19-
private Context mContext;
24+
private UncaughtExceptionHandler mHandler;
25+
private String mAndroidVersion;
26+
private String mModel;
27+
private String mManufacturer;
28+
public static String sVERSION = "Unknown";
29+
private static CrashBuilder sBuilder;
30+
private boolean isAppend;
31+
private boolean isSimple;
2032

2133
private CrashUtils() {
22-
throw new AssertionError();
34+
mHandler = Thread.currentThread().getUncaughtExceptionHandler();
35+
Thread.currentThread().setUncaughtExceptionHandler(this);
36+
mAndroidVersion = Build.VERSION.RELEASE;//安卓系统版本
37+
mModel = Build.MODEL;// 设备型号
38+
mManufacturer = Build.MANUFACTURER;// 设备厂商
2339
}
2440

25-
public static CrashUtils getInstance() {
26-
if (INSTANCE == null)
27-
INSTANCE = new CrashUtils();
28-
return INSTANCE;
41+
/**
42+
* @param isAppend 是否为日志追加模式
43+
*/
44+
public CrashUtils setAppend(boolean isAppend) {
45+
this.isAppend = isAppend;
46+
return this;
47+
}
48+
49+
/**
50+
* @param isSimple 是否为简单的日志记录模式
51+
*/
52+
public CrashUtils setSimple(boolean isSimple) {
53+
this.isSimple = isSimple;
54+
return this;
2955
}
3056

31-
public void init(Context context) { // 在Application中初始化
32-
mContext = context;
3357

34-
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 获取系统默认的UncaughtException处理器
35-
Thread.setDefaultUncaughtExceptionHandler(this);// 设置该CrashHandler为程序的默认处理器
58+
public static CrashUtils init(Context context, String dirName) {
59+
try {
60+
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
61+
sVERSION = info.versionName + info.versionCode;
62+
sBuilder = CrashBuilder.build(context, dirName);
63+
} catch (Exception e) {
64+
throw new RuntimeException(e);
65+
}
66+
return new CrashUtils();
3667
}
68+
69+
// public static String formatNumber(int value) {
70+
// return new DecimalFormat("00").format(value);
71+
// }
72+
//
73+
// public static String getCurrentDate() {
74+
// Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
75+
// return calendar.get(Calendar.YEAR) + "-" + formatNumber((calendar.get(Calendar.MONTH) + 1)) + "-"
76+
// + formatNumber(calendar.get(Calendar.DAY_OF_MONTH)) + " "
77+
// + formatNumber(calendar.get(Calendar.HOUR_OF_DAY)) + ":" + formatNumber(calendar.get(Calendar
78+
// .MINUTE));
79+
// }
80+
3781
@Override
38-
public void uncaughtException(Thread thread, Throwable ex) {
39-
if (!handleException(ex) && mDefaultHandler != null) {
40-
// 如果自定义的没有处理则让系统默认的异常处理器来处理
41-
mDefaultHandler.uncaughtException(thread, ex);
82+
public void uncaughtException(Thread thread, Throwable throwable) {
83+
if (!isAppend) {
84+
FileUtils.createFileByDeleteOldFile(sBuilder.getCarsh_log());
85+
} else {
86+
FileUtils.createOrExistsFile(sBuilder.getCarsh_log());
87+
}
88+
File file = new File(sBuilder.getCarsh_log());
89+
PrintWriter pw = null;
90+
try {
91+
pw = new PrintWriter(new FileWriter(file, true));
92+
pw.write("\n*************---------Crash Log Head ------------****************\n\n");
93+
pw.write("Happened Time: " + TimeUtils.getCurTimeString() + "\n");
94+
pw.write("Android Version: " + mAndroidVersion + "\n");
95+
pw.write("Device Model: " + mModel + "\n");
96+
pw.write("Device Manufacturer: " + mManufacturer + "\n");
97+
pw.write("App Version: v" + sVERSION + "\n\n");
98+
pw.write("*************---------Crash Log Head ------------****************\n\n");
99+
if (!isSimple)
100+
throwable.printStackTrace(pw);
101+
else {
102+
pw.write(throwable.getLocalizedMessage() + "\n");
103+
}
104+
} catch (IOException e) {
105+
return;
106+
} finally {
107+
FileUtils.closeIO(pw);
108+
}
109+
FileUtils.createFileByDeleteOldFile(sBuilder.getCrash_tag());
110+
if (mHandler != null) {
111+
mHandler.uncaughtException(thread, throwable);
42112
}
43113
}
44114

45-
/**
46-
* 自定义错误处理、收集错误信息、发送错误报告
47-
*
48-
* @param ex 异常信息
49-
* @return true 如果处理了该异常信息;否则返回false.
50-
*/
51-
public boolean handleException(Throwable ex) {
52-
if (ex == null || mContext == null)
53-
return false;
54-
final String crashReport = getCrashReport(mContext, ex);
55-
new Thread() {
56-
public void run() {
57-
Looper.prepare();
58-
LogUtils.e("CrashHandler", crashReport); // 打印异常信息,也可保存至文件 方便远程调试
59-
Looper.loop();
115+
public static class CrashBuilder {
116+
private String carsh_dir;
117+
public String getCrash_dir() {
118+
return carsh_dir;
119+
}
120+
public String getCarsh_log() {
121+
return getCrash_dir() + File.separator + "carshRecord.log";
122+
}
123+
public String getCrash_tag() {
124+
return getCrash_dir() + File.separator + ".carshed";
125+
}
126+
public CrashBuilder(Context context, String dirName) {
127+
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
128+
this.carsh_dir = context.getCacheDir().getPath() + File.separator + dirName;
129+
} else {
130+
this.carsh_dir = context.getExternalCacheDir().getPath() + File.separator + dirName;
60131
}
132+
}
133+
public static CrashBuilder build(Context context, String dirName) {
134+
return new CrashBuilder(context, dirName);
135+
}
61136

62-
}.start();
63-
return true;
137+
@Override
138+
public String toString() {
139+
return "CarshBuilder [dir path: " + getCrash_dir() + "-- log path:" + getCarsh_log() + "-- tag path:" +
140+
getCrash_tag() + "]";
141+
}
64142
}
65143

66144
/**
67-
* 获取APP崩溃异常报告
68-
*
69-
* @param ex
70-
* @return
145+
* 获取log 日志路径
71146
*/
72-
private String getCrashReport(Context context, Throwable ex) {
73-
// PackageInfo pinfo = AppUtils.getPackageInfo(context);
74-
StringBuffer exceptionStr = new StringBuffer();
75-
// exceptionStr.append("Version: " + pinfo.versionName + "(" + pinfo.versionCode + ")\n");
76-
exceptionStr.append("Android: " + android.os.Build.VERSION.RELEASE + "(" + android.os.Build.MODEL + ")\n");
77-
exceptionStr.append("Exception: " + ex.getMessage() + "\n");
78-
StackTraceElement[] elements = ex.getStackTrace();
79-
for (int i = 0; i < elements.length; i++) {
80-
exceptionStr.append(elements[i].toString() + "\n");
81-
}
82-
return exceptionStr.toString();
147+
public static String getLogFilePath() {
148+
if (sBuilder == null)
149+
return "Unknown";
150+
else
151+
return sBuilder.getCarsh_log();
152+
}
153+
154+
/**
155+
* 获取 LOG 记录的内容
156+
*/
157+
public static String getLogContent() {
158+
return FileUtils.readFile2String(getLogFilePath(), "UTF-8");
83159
}
84160
}

0 commit comments

Comments
 (0)