Skip to content

Commit 733a60a

Browse files
author
GaoLei
committed
1、优化CrashHandler
1 parent 882fd61 commit 733a60a

File tree

4 files changed

+236
-131
lines changed

4 files changed

+236
-131
lines changed

MVPModel/app/src/main/java/com/gaolei/mvpmodel/application/CrashHandler.java

Lines changed: 0 additions & 131 deletions
This file was deleted.

MVPModel/app/src/main/java/com/gaolei/mvpmodel/application/CustomApplication.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.bumptech.glide.request.RequestOptions;
1414
import com.gaolei.mvpmodel.BuildConfig;
1515
import com.gaolei.mvpmodel.R;
16+
import com.gaolei.mvpmodel.base.utils.CrashHandler;
1617
import com.github.moduth.blockcanary.BlockCanary;
1718
import com.github.moduth.blockcanary.BlockCanaryContext;
1819
import com.squareup.leakcanary.LeakCanary;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package com.gaolei.mvpmodel.base.utils;
2+
3+
import android.app.AlarmManager;
4+
import android.app.PendingIntent;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
import android.content.pm.PackageInfo;
8+
import android.content.pm.PackageManager;
9+
import android.os.Environment;
10+
import android.os.Looper;
11+
import android.view.Gravity;
12+
import android.widget.Toast;
13+
14+
15+
import com.gaolei.mvpmodel.application.CustomApplication;
16+
17+
import java.io.File;
18+
import java.io.FileOutputStream;
19+
import java.io.PrintWriter;
20+
import java.io.StringWriter;
21+
import java.io.Writer;
22+
import java.text.SimpleDateFormat;
23+
import java.util.Date;
24+
import java.util.LinkedHashMap;
25+
import java.util.Map;
26+
27+
public class CrashHandler implements Thread.UncaughtExceptionHandler {
28+
/**
29+
* 系统默认的异常处理类
30+
*/
31+
private Thread.UncaughtExceptionHandler mDefaultHandler;
32+
Context mcontext;
33+
private static CrashHandler INSTANCE = new CrashHandler();
34+
String errorSavePath;
35+
//用来存储设备信息和异常信息
36+
private Map<String, String> infos = new LinkedHashMap();
37+
38+
public static CrashHandler getInstance() {
39+
return INSTANCE;
40+
}
41+
42+
public void init(Context context) {
43+
mcontext = context;
44+
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 获取默认的异常处理类
45+
Thread.setDefaultUncaughtExceptionHandler(this);// 设置当前处理类为默认的异常处理类
46+
}
47+
48+
@Override
49+
public void uncaughtException(Thread thread, Throwable ex) {
50+
if (!handleException(ex) && mDefaultHandler != null) {
51+
mDefaultHandler.uncaughtException(thread, ex);// 如果未处理异常,那么系统默认的异常处理类处理
52+
} else {
53+
try {
54+
Thread.sleep(1500);
55+
} catch (Exception e) {
56+
// TODO: handle exception
57+
}
58+
59+
60+
61+
//崩溃后,重启应用
62+
Intent intent = new Intent();
63+
intent.setAction(Intent.ACTION_MAIN);
64+
intent.putExtra("error_reboot", true);
65+
66+
PendingIntent pendingIntent = PendingIntent.getActivity(
67+
mcontext.getApplicationContext(), 0, intent,
68+
PendingIntent.FLAG_ONE_SHOT);
69+
AlarmManager mgr = (AlarmManager) mcontext
70+
.getSystemService(Context.ALARM_SERVICE);
71+
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1500,
72+
pendingIntent); // 1秒钟后重启应用
73+
android.os.Process.killProcess(android.os.Process.myPid());
74+
System.exit(10);
75+
}
76+
}
77+
78+
private boolean handleException(Throwable ex) {
79+
if (ex == null) {
80+
return false;
81+
}
82+
new Thread() {
83+
@Override
84+
public void run() {
85+
Looper.prepare();
86+
Toast toast = Toast.makeText(mcontext, "程序出错了,我们会尽快修复,稍后将重启应用!",
87+
Toast.LENGTH_LONG);
88+
toast.setGravity(Gravity.CENTER, 0, 0);
89+
toast.show();
90+
Looper.loop();
91+
}
92+
}.start();
93+
94+
collectDeviceInfo();
95+
saveCrashInfoIntoSd(ex);
96+
return true;// 测试阶段全部抛出
97+
// return false;
98+
}
99+
100+
// 收集设备、软件参数信息
101+
private void collectDeviceInfo() {
102+
try {
103+
PackageManager pm = CustomApplication.context.getPackageManager();
104+
PackageInfo pi = pm.getPackageInfo(CustomApplication.context.getPackageName(), PackageManager.GET_ACTIVITIES);
105+
if (pi != null) {
106+
String versionName = pi.versionName == null ? "null" : pi.versionName;
107+
String versionCode = pi.versionCode + "";
108+
infos.put("systemVersion", SystemUtil.getSystemVersion());
109+
infos.put("deviceModel", SystemUtil.getSystemModel());
110+
infos.put("deviceBrand", SystemUtil.getDeviceBrand());
111+
infos.put("versionName", versionName);
112+
infos.put("versionCode", versionCode);
113+
}
114+
} catch (PackageManager.NameNotFoundException e) {
115+
}
116+
117+
}
118+
119+
// 保存错误信息到SD卡文件中
120+
private void saveCrashInfoIntoSd(Throwable ex) {
121+
//创建文件夹
122+
errorSavePath = Environment.getExternalStorageDirectory().getPath() + "/" + mcontext.getPackageName() + "/crash";
123+
File dir = new File(errorSavePath);
124+
if (!dir.exists()) dir.mkdirs();
125+
126+
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
127+
String time = formatter.format(new Date());
128+
StringBuffer sb = new StringBuffer();
129+
sb.append("\n" + time + "\n");
130+
for (Map.Entry<String, String> entry : infos.entrySet()) {
131+
String key = entry.getKey();
132+
String value = entry.getValue();
133+
sb.append(key + "=" + value + "\n");
134+
}
135+
136+
sb.append(getCrashInfo(ex));
137+
138+
try {
139+
//创建文件
140+
String fileName = "crash-" + time + ".txt";
141+
File file = new File(errorSavePath + "//" + fileName);
142+
if (!file.exists()) file.createNewFile();
143+
144+
FileOutputStream fos = new FileOutputStream(file);
145+
fos.write(sb.toString().getBytes());
146+
fos.close();
147+
} catch (Exception e) {
148+
e.printStackTrace();
149+
}
150+
}
151+
152+
/**
153+
* 得到程序崩溃的详细信息
154+
*/
155+
public String getCrashInfo(Throwable ex) {
156+
Writer result = new StringWriter();
157+
PrintWriter printWriter = new PrintWriter(result);
158+
ex.setStackTrace(ex.getStackTrace());
159+
ex.printStackTrace(printWriter);
160+
printWriter.close();
161+
return result.toString();
162+
}
163+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.gaolei.mvpmodel.base.utils;
2+
3+
import android.app.Activity;
4+
import android.content.Context;
5+
import android.telephony.TelephonyManager;
6+
7+
import java.util.Locale;
8+
9+
/**
10+
* 系统工具类
11+
* Created by zhuwentao on 2016-07-18.
12+
*/
13+
public class SystemUtil {
14+
15+
/**
16+
* 获取当前手机系统语言。
17+
*
18+
* @return 返回当前系统语言。例如:当前设置的是“中文-中国”,则返回“zh-CN”
19+
*/
20+
public static String getSystemLanguage() {
21+
return Locale.getDefault().getLanguage();
22+
}
23+
24+
/**
25+
* 获取当前系统上的语言列表(Locale列表)
26+
*
27+
* @return 语言列表
28+
*/
29+
public static Locale[] getSystemLanguageList() {
30+
return Locale.getAvailableLocales();
31+
}
32+
33+
/**
34+
* 获取当前手机系统版本号
35+
*
36+
* @return 系统版本号
37+
*/
38+
public static String getSystemVersion() {
39+
return android.os.Build.VERSION.RELEASE;
40+
}
41+
42+
/**
43+
* 获取手机型号
44+
*
45+
* @return 手机型号
46+
*/
47+
public static String getSystemModel() {
48+
return android.os.Build.MODEL;
49+
}
50+
51+
/**
52+
* 获取手机厂商
53+
*
54+
* @return 手机厂商
55+
*/
56+
public static String getDeviceBrand() {
57+
return android.os.Build.BRAND;
58+
}
59+
60+
/**
61+
* 获取手机IMEI(需要“android.permission.READ_PHONE_STATE”权限)
62+
*
63+
* @return 手机IMEI
64+
*/
65+
// public static String getIMEI(Context ctx) {
66+
// TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
67+
// if (tm != null) {
68+
// return tm.getDeviceId();
69+
// }
70+
// return null;
71+
// }
72+
}

0 commit comments

Comments
 (0)