个人笔记
/**
* Created by jian on 2017/7/11.
*/
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static CrashHandler instance = null;
private Thread.UncaughtExceptionHandler mDefaultHandler;
private Map<String, String> mInfo = new HashMap<>();
//日期格式化
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private CrashHandler() {
}
/**
* 单例模式,懒汉
*
* @return
*/
public static CrashHandler getCrashHandler() {
if (instance == null) {
synchronized (CrashHandler.class) {
if (instance == null) {
instance = new CrashHandler();
}
}
}
return instance;
}
private Context mContext;
/**
* 初始化
*
* @param context
*/
public void init(Context context) {
mContext = context;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();//获得默认的的未被捕捉的异常
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
//收集错误信息
//保存错误信息
//上传错误信息到服务器
if (!handleException(e)) {
//未被处理,调用系统默认的处理器处理
if (mDefaultHandler != null) {
mDefaultHandler.uncaughtException(t, e);
} else {
//已经人为处理
try {
//休眠一秒钟后退出
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Process.killProcess(Process.myPid());
System.exit(1);
}
}
}
/**
* 人为处理异常
*
* @param e
* @return
*/
private boolean handleException(Throwable e) {
if (e == null) {
return false;
}
//toast提示
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, "UncaughtException", Toast.LENGTH_SHORT).show();
Looper.loop();
}
}.start();
//收集错误信息
collectErrorInfo();
//
saveErrorInfo(e);
return false;
}
private void saveErrorInfo(Throwable e) {
StringBuffer stringBuffer = new StringBuffer();
for (Map.Entry<String, String> entry : mInfo.entrySet()) {
String keyName = entry.getKey();
String value = entry.getValue();
stringBuffer.append(keyName + "=" + value + "\n");//把错误信息写到Buffer中
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
e.printStackTrace();
Throwable cause = e.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = e.getCause();
}
printWriter.close();
String result = writer.toString();
stringBuffer.append(result);
//获取当前时间
long cruTime = System.currentTimeMillis();
//格式化
String time = dateFormat.format(cruTime);
String fileName = "crash-" + time + "." + cruTime + ".log";
//判断是否有SD卡
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = "/sdcard/crash";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
//错误信息写入SD卡
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path + fileName);
fos.write(stringBuffer.toString().getBytes());
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
private void collectErrorInfo() {
PackageManager manager = mContext.getPackageManager();
try {
PackageInfo pi = manager.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
//版本名字
String versionName = TextUtils.isEmpty(pi.versionName) ? "未设置版本名称" : pi.versionName;
//版本号
String versionCode = pi.versionCode + "";
mInfo.put("versionName", versionName);
mInfo.put("versionCode", versionCode);
}
Field[] fields = Build.class.getFields();
if (fields != null && fields.length > 0) {
for (Field field : fields) {
field.setAccessible(true);
try {
mInfo.put(field.getName(), field.get(null).toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
}
在Application中
/**
* Created by jian on 2017/7/11.
*/
public class CrashApplication extends Application {
private CrashHandler crashHandler;
@Override
public void onCreate() {
super.onCreate();
crashHandler = CrashHandler.getCrashHandler();
crashHandler.init(this);
}
}