package com.zeushotfix.wrap;
import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import java.io.File;
/**
* Created by huangjian on 2017/5/17.
*/
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static final String CRASH_TIME = "hotfix_crash_time"; //补丁崩溃时存放崩溃时间的文件的文件名
private static CrashHandler instance;
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultHandler; // 系统默认的UncaughtException处理类
private CrashHandler() {
}
/**
* 获取CrashHandler实例 ,单例模式
*/
public static CrashHandler getInstance() {
if (instance == null) {
synchronized (CrashHandler.class) {
if (instance == null) {
instance = new CrashHandler();
}
}
}
return instance;
}
public void init(Context context) {
mContext = context;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
onCrash(mContext);
if (mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);
}
}
/**
* 获取记录崩溃时间的文件的地址
*
* @param context context
* @return 记录崩溃时间的文件的地址
*/
private String getCrashTimeFilePath(Context context) {
try {
return context.getExternalCacheDir().getAbsolutePath() + File.separator + CRASH_TIME;
} catch (Throwable e) {
return Environment.getExternalStorageDirectory().getPath() + "/Android/data/" + context.getPackageName() + "/cache/" + CRASH_TIME;
}
}
/**
* 当发生崩溃时调用,防止错误的补丁导致软件无法启动
*
* @param context context
*/
public void onCrash(Context context) {
String cacheDir;
try {
cacheDir = context.getExternalCacheDir().getAbsolutePath();
} catch (Throwable e) {
cacheDir = Environment.getExternalStorageDirectory().getPath() + "/Android/data/" + context.getPackageName() + "/cache/";
}
if (context.getPackageCodePath().startsWith(cacheDir)) {
long nowTime = System.currentTimeMillis();
String crashTimeString = Util.readString(getCrashTimeFilePath(context));
if (!TextUtils.isEmpty(crashTimeString)) {
long crashTime = Long.valueOf(crashTimeString);
long delTime = nowTime - crashTime;
if (delTime > 0 && delTime < 2 * 60 * 1000) {//2分钟内再次发生崩溃
Util.deleteDirectorySafe(new File(Util.getInsideHotfixPath(context)));
Util.deleteDirectorySafe(new File(Util.getSdcardHotfixPath(context)));
} else {
Util.writeString(getCrashTimeFilePath(context), String.valueOf(nowTime));
}
} else {
Util.writeString(getCrashTimeFilePath(context), String.valueOf(nowTime));
}
}
}
}