重启
CrashManagerInitConfigure
package widget.crash;
import android.app.Application;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.SystemClock;
import androidx.annotation.NonNull;
import com.zsp.utilone.intent.IntentUtils;
import com.zsp.utilone.log.ErrorLogManager;
import com.zsp.utilone.log.LogManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import value.Folder;
/**
* Created on 2018/5/24.
*
* @author 郑少鹏
* @desc 崩溃管理器初始化配置
*/
public class CrashManagerInitConfigure implements Thread.UncaughtExceptionHandler {
private static final String TAG = "CrashManager";
/**
* 实例
*/
private static CrashManagerInitConfigure instance;
/**
* Application
*/
private Application application;
/**
* 系统默UncaughtException处理类
*/
private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
/**
* 存设备信息和异常信息
*/
private Map<String, String> information = new HashMap<>();
/**
* 格式化日期(日志文件名部分)
*/
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.CHINA);
/**
* 仅一CrashHandler实例
*
* @param application Application
*/
private CrashManagerInitConfigure(Application application) {
this.application = application;
uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* CrashHandler实例
*
* @param application Application
*/
public static void getInstance(Application application) {
CrashManagerInitConfigure crashManagerInitConfigure = instance;
if (crashManagerInitConfigure == null) {
synchronized (CrashManagerInitConfigure.class) {
crashManagerInitConfigure = instance;
if (crashManagerInitConfigure == null) {
crashManagerInitConfigure = new CrashManagerInitConfigure(application);
instance = crashManagerInitConfigure;
}
}
}
}
/**
* UncaughtException时转该函数处理
*
* @param thread 线程
* @param throwable 异常
*/
@Override
public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
LogManager.e(TAG, thread.getName(), throwable);
if (!handleException(throwable) && uncaughtExceptionHandler != null) {
// 程序没处理则系统默异常处理器处理
uncaughtExceptionHandler.uncaughtException(thread, throwable);
} else {
SystemClock.sleep(500);
// 重启
IntentUtils.restart(application);
// 杀已崩进程
android.os.Process.killProcess(android.os.Process.myPid());
}
}
/**
* 自定错误处理
* <p>
* 收集错误信息、发送错误报告等均在此完成。
*
* @param throwable 异常
* @return true处理异常,不再上抛;false不处理异常,存信息并交上层(系统异常处理器)处理
*/
private boolean handleException(Throwable throwable) {
if (throwable == null) {
return false;
}
// 收集设备参数信息
collectDeviceInfo(application);
// 存错误信息至文件
saveCrashInfoToFile(throwable);
return true;
}
/**
* 收设备参数信息
*
* @param application Application
*/
private void collectDeviceInfo(Application application) {
try {
PackageManager pm = application.getPackageManager();
PackageInfo pi = pm.getPackageInfo(application.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
information.put("versionName", versionName);
information.put("versionCode", versionCode);
}
} catch (PackageManager.NameNotFoundException e) {
ErrorLogManager.e(TAG, "an error occurred when collecting package info", e);
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
information.put(field.getName(), Objects.requireNonNull(field.get(null), "must not be null").toString());
} catch (Exception e) {
ErrorLogManager.e(TAG, "an error occurred when collecting crash info", e);
}
}
}
/**
* 存错误信息至文件
*
* @param throwable 异常
*/
private void saveCrashInfoToFile(Throwable throwable) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : information.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key).append("=").append(value).append("\n");
}
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
throwable.printStackTrace(printWriter);
Throwable cause = throwable.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
try {
String time = dateFormat.format(new Date());
String fileName = "lll" + time + ".log";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = Folder.CRASH;
File dir = new File(path);
if (!dir.exists() && dir.mkdirs()) {
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
LogManager.eTag("saveCrashInfoToFile", sb.toString());
fos.close();
} else {
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
LogManager.eTag("saveCrashInfoToFile", sb.toString());
fos.close();
}
}
} catch (Exception e) {
ErrorLogManager.e(TAG, "An error occurred while writing to file.", e);
}
}
}
Application
CrashManagerInitConfigure.getInstance(this);
退出
package widget.crash;
import android.app.Application;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.SystemClock;
import androidx.annotation.NonNull;
import com.zsp.utilone.activity.ActivitySuperviseManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import timber.log.Timber;
import value.Folder;
/**
* Created on 2018/5/24.
*
* @author 郑少鹏
* @desc 崩溃管理器初始化配置
*/
public class CrashManagerInitConfigure implements Thread.UncaughtExceptionHandler {
/**
* 实例
*/
private static CrashManagerInitConfigure instance;
/**
* Application
*/
private Application application;
/**
* 系统默UncaughtException处理类
*/
private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
/**
* 存设备信息和异常信息
*/
private Map<String, String> information = new HashMap<>();
/**
* 格式化日期(日志文件名部分)
*/
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.CHINA);
/**
* 仅一CrashHandler实例
*
* @param application Application
*/
private CrashManagerInitConfigure(Application application) {
this.application = application;
uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* CrashHandler实例
*
* @param application Application
*/
public static void getInstance(Application application) {
CrashManagerInitConfigure crashManagerInitConfigure = instance;
if (crashManagerInitConfigure == null) {
synchronized (CrashManagerInitConfigure.class) {
crashManagerInitConfigure = instance;
if (crashManagerInitConfigure == null) {
crashManagerInitConfigure = new CrashManagerInitConfigure(application);
instance = crashManagerInitConfigure;
}
}
}
}
/**
* UncaughtException时转该函数处理
*
* @param thread 线程
* @param throwable 异常
*/
@Override
public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
Timber.e(throwable);
if (!handleException(throwable) && uncaughtExceptionHandler != null) {
// 程序没处理则系统默异常处理器处理
uncaughtExceptionHandler.uncaughtException(thread, throwable);
} else {
SystemClock.sleep(200);
// 退应用
ActivitySuperviseManager.appExit();
// 杀已崩进程
android.os.Process.killProcess(android.os.Process.myPid());
}
}
/**
* 自定错误处理
* <p>
* 收集错误信息、发送错误报告等均在此完成。
*
* @param throwable 异常
* @return true处理异常,不再上抛;false不处理异常,存信息并交上层(系统异常处理器)处理
*/
private boolean handleException(Throwable throwable) {
if (throwable == null) {
return false;
}
// 收集设备参数信息
collectDeviceInfo(application);
// 存错误信息至文件
saveCrashInfoToFile(throwable);
return true;
}
/**
* 收设备参数信息
*
* @param application Application
*/
private void collectDeviceInfo(Application application) {
try {
PackageManager pm = application.getPackageManager();
PackageInfo pi = pm.getPackageInfo(application.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
information.put("versionName", versionName);
information.put("versionCode", versionCode);
}
} catch (PackageManager.NameNotFoundException e) {
Timber.e(e, "an error occurred when collecting package info");
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
information.put(field.getName(), Objects.requireNonNull(field.get(null), "must not be null").toString());
} catch (Exception e) {
Timber.e(e, "an error occurred when collecting crash info");
}
}
}
/**
* 存错误信息至文件
*
* @param throwable 异常
*/
private void saveCrashInfoToFile(Throwable throwable) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : information.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key).append("=").append(value).append("\n");
}
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
throwable.printStackTrace(printWriter);
Throwable cause = throwable.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
try {
String time = dateFormat.format(new Date());
String fileName = "lll" + time + ".log";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = Folder.CRASH;
File dir = new File(path);
if (!dir.exists() && dir.mkdirs()) {
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
Timber.d(sb.toString());
fos.close();
} else {
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
Timber.d(sb.toString());
fos.close();
}
}
} catch (Exception e) {
Timber.e(e);
}
}
}
Application
CrashManagerInitConfigure.getInstance(this);
弹窗
需跳页实现。