[CrashFix]优化异常捕获逻辑
[xxx]
This commit is contained in:
@@ -230,7 +230,7 @@ aspectjx {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||
//Crash日志收集
|
||||
implementation rootProject.ext.dependencies.crashSdk
|
||||
// implementation rootProject.ext.dependencies.crashSdk
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
implementation rootProject.ext.dependencies.boostmultidex
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.mogo.launcher;
|
||||
|
||||
import com.auto.zhidao.logsdk.CrashSystem;
|
||||
import com.mogo.eagle.core.function.main.MainMoGoApplication;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
|
||||
import com.mogo.launcher.crash.CrashSystem;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
@@ -17,7 +17,6 @@ public class MogoApplication extends MainMoGoApplication {
|
||||
protected void initCrashConfig() {
|
||||
CrashSystem crashSystem = CrashSystem.getInstance(this);
|
||||
crashSystem.init();
|
||||
|
||||
//设置debug模式,日志不上传
|
||||
crashSystem.setDebug(BuildConfig.DEBUG);
|
||||
}
|
||||
|
||||
218
app/src/main/java/com/mogo/launcher/crash/CrashSystem.java
Normal file
218
app/src/main/java/com/mogo/launcher/crash/CrashSystem.java
Normal file
@@ -0,0 +1,218 @@
|
||||
package com.mogo.launcher.crash;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class CrashSystem implements UncaughtExceptionHandler {
|
||||
public static final String TAG = "CrashSystem";
|
||||
private String mAppPackage = null;
|
||||
private String mAppVersionCode = null;
|
||||
private String mAppVersionName = null;
|
||||
private String mAppName = null;
|
||||
private String mOsVersion = null;
|
||||
private String mDeviceId = null;
|
||||
private UncaughtExceptionHandler mDefaultHandler;
|
||||
private final Map<String, String> info = new HashMap();
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||
private boolean mDebug = false;
|
||||
private final List<CrashCallback> callbackList = new ArrayList<>();
|
||||
|
||||
private static CrashSystem sCrashSystem = null;
|
||||
|
||||
private static final Object lock = new Object();
|
||||
|
||||
public void init() {
|
||||
this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否收集记录crash信息
|
||||
* @param debug 是否是debug
|
||||
*/
|
||||
public void setDebug(boolean debug) {
|
||||
this.mDebug = debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加crash事件回调
|
||||
*/
|
||||
public void addCallback(CrashCallback callback) {
|
||||
if(callback != null) {
|
||||
callbackList.add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
private CrashSystem(Context context) {
|
||||
this.inflateSystemInfo(context);
|
||||
}
|
||||
|
||||
public static CrashSystem getInstance(Context context) {
|
||||
CrashSystem crashSystem = sCrashSystem;
|
||||
if(crashSystem == null) {
|
||||
synchronized (lock) {
|
||||
crashSystem = sCrashSystem;
|
||||
if(crashSystem == null) {
|
||||
crashSystem = new CrashSystem(context.getApplicationContext());
|
||||
sCrashSystem = crashSystem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crashSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread thread, Throwable ex) {
|
||||
try {
|
||||
this.handleException(ex);
|
||||
dispatchCrashError();
|
||||
} finally {
|
||||
if (mDefaultHandler != null) {
|
||||
mDefaultHandler.uncaughtException(thread, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分发异常事件
|
||||
*/
|
||||
private void dispatchCrashError() {
|
||||
for (CrashCallback callback : callbackList) {
|
||||
if(callback != null) {
|
||||
callback.onCrashError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleException(Throwable ex) {
|
||||
if(ex == null) {
|
||||
return true;
|
||||
} else {
|
||||
String msg = ex.getLocalizedMessage();
|
||||
Log.e("CrashSystem", msg);
|
||||
String filePath = saveCrashInfo2File(ex);
|
||||
Log.i(TAG, "handleException: filePath = " + filePath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private String saveCrashInfo2File(Throwable ex) {
|
||||
try {
|
||||
if(!Environment.getExternalStorageState().equals("mounted")) {
|
||||
return null;
|
||||
}
|
||||
File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "crash");
|
||||
if(!dir.exists()) {
|
||||
dir.mkdir();
|
||||
}
|
||||
String[] fileList = dir.list((dir1, name) -> name.contains(mAppPackage));
|
||||
if(fileList == null || fileList.length >= 20) { //避免crash日志一直重复
|
||||
return null;
|
||||
}
|
||||
String time = this.format.format(new Date());
|
||||
String fileName = "app-crash-" + this.mAppPackage + "-" + time + ".log";
|
||||
if(mDebug) {
|
||||
fileName = "debug-" + fileName;
|
||||
}
|
||||
String fileTemp = fileName + ".temp";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Iterator<Entry<String, String>> var4 = this.info.entrySet().iterator();
|
||||
String result;
|
||||
while(var4.hasNext()) {
|
||||
Entry<String, String> entry = var4.next();
|
||||
String key = entry.getKey();
|
||||
result = entry.getValue();
|
||||
sb.append(key).append("=").append(result).append("\n");
|
||||
}
|
||||
sb.append("TIME=").append(String.valueOf(System.currentTimeMillis())).append("\n");
|
||||
sb.append("fileName=").append(fileName).append("\n");
|
||||
Writer writer = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(writer);
|
||||
ex.printStackTrace(pw);
|
||||
for(Throwable cause = ex.getCause(); cause != null; cause = cause.getCause()) {
|
||||
cause.printStackTrace(pw);
|
||||
}
|
||||
pw.close();
|
||||
result = writer.toString();
|
||||
sb.append(result);
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
File dest = new File(dir, fileTemp);
|
||||
fos = new FileOutputStream(dest);
|
||||
fos.write(sb.toString().getBytes());
|
||||
fos.flush();
|
||||
File file = new File(dir,fileName);
|
||||
dest.renameTo(file);
|
||||
return dir.getAbsolutePath() + File.separator + fileName;
|
||||
} catch (IOException var13) {
|
||||
var13.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void inflateSystemInfo(Context context) {
|
||||
this.mAppPackage = context.getPackageName();
|
||||
PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
PackageInfo packageInfo = pm.getPackageInfo(this.mAppPackage, 0);
|
||||
this.mAppVersionCode = "" + packageInfo.versionCode;
|
||||
this.mAppVersionName = packageInfo.versionName;
|
||||
this.mAppPackage = packageInfo.packageName;
|
||||
this.mAppName = packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString();
|
||||
this.mOsVersion = Build.DISPLAY;
|
||||
String deviceId = MoGoAiCloudClientConfig.getInstance().getSn();
|
||||
if(TextUtils.isEmpty(deviceId)) {
|
||||
deviceId = "11111111";
|
||||
}
|
||||
this.mDeviceId = deviceId;
|
||||
} catch (Exception var5) {
|
||||
var5.printStackTrace();
|
||||
}
|
||||
|
||||
this.info.put("appName",this.mAppName);
|
||||
this.info.put("appPackageName", this.mAppPackage);
|
||||
this.info.put("versionCode", this.mAppVersionCode);
|
||||
this.info.put("versionName", this.mAppVersionName);
|
||||
this.info.put("sn", this.mDeviceId);
|
||||
this.info.put("DISPLAY", this.mOsVersion);
|
||||
}
|
||||
|
||||
public interface CrashCallback {
|
||||
void onCrashError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,6 @@ ext {
|
||||
jetbrainsannotationsjava5 : "org.jetbrains:annotations-java5:15.0",
|
||||
|
||||
// crash
|
||||
crashSdk : "com.zhidaoauto.crash.log:library:1.0.5",
|
||||
kotlinstdlibjdk7 : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlin_version}",
|
||||
|
||||
//探路使用的直播组件
|
||||
|
||||
@@ -62,7 +62,7 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.androidxroomktx
|
||||
|
||||
//Crash日志收集
|
||||
implementation rootProject.ext.dependencies.crashSdk
|
||||
// implementation rootProject.ext.dependencies.crashSdk
|
||||
implementation rootProject.ext.dependencies.boostmultidex
|
||||
|
||||
debugImplementation rootProject.ext.dependencies.debugleakcanary
|
||||
|
||||
Reference in New Issue
Block a user