未捕获异常自动重启app

serial
Matthew 1 year ago
parent e57843cdb0
commit 87aac90d58

@ -180,6 +180,22 @@ public class MicroPhotoContext {
return path;
}
public static String buildMasterAppDir(Context contxt) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
if (!path.endsWith(File.separator)) {
path += File.separator;
}
path += PACKAGE_NAME_MPMASTER + File.separator;
File pathFile = new File(path);
if (!pathFile.exists() && !pathFile.mkdirs()) {
return null;
}
return path;
}
public static AppConfig getMpAppConfig(Context context) {
AppConfig appConfig = new AppConfig();

@ -104,5 +104,6 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.orhanobut:logger:2.2.0'
implementation files('libs/devapi.aar')
}

@ -68,6 +68,7 @@
tools:ignore="ProtectedPermissions" />
<application
android:name=".MpMstApplication"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"

@ -0,0 +1,176 @@
package com.xypower.mpmaster;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import com.xypower.common.MicroPhotoContext;
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.Map;
public class CrashHandler implements Thread.UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
private static CrashHandler INSTANCE = new CrashHandler();
/**
* UncaughtException
**/
private Thread.UncaughtExceptionHandler mDefaultHandler;
/**
*
**/
private Map<String, String> mInfos = new HashMap<String, String>();
private DateFormat mFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
public CrashHandler() {
}
public static CrashHandler getInstance() {
return INSTANCE;
}
public void init() {
// 获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* @: UncaughtException
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Log.e(this.getClass().toString(), e == null ? "" : e.toString());
}
// 重新启动应用
Intent intent = new Intent(MpMstApplication.getContext(), MainActivity.class);
PendingIntent restartIntent = PendingIntent.getActivity(MpMstApplication.getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager mgr = (AlarmManager) MpMstApplication.getContext().getSystemService(Context.ALARM_SERVICE);
// 1秒钟后重启应用
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent);
// todo:退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}
/**
* @return true:;false.
* @throws
* @:, .
*/
private boolean handleException(Throwable ex) {
if (null == ex) {
return false;
}
// 收集设备参数信息
collectDeviceInfo(MpMstApplication.getContext());
// 保存日志文件
saveCrashInfo2File(ex);
return true;
}
/**
* @:
*/
private void collectDeviceInfo(Context context) {
try {
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
mInfos.put("versionName", versionName);
mInfos.put("versionCode", versionCode);
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "an error occured when collect package info", e);
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
mInfos.put(field.getName(), field.get(null).toString());
Log.d(TAG, field.getName() + " : " + field.get(null));
} catch (Exception e) {
Log.e(TAG, "an error occured when collect crash info", e);
}
}
}
/**
* @throws
* @: /sdcard/qfangadtv/crash/
* @ void ,便
*/
private String saveCrashInfo2File(Throwable ex) {
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> entry : mInfos.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key + "=" + value + "\n");
}
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
try {
long timestamp = System.currentTimeMillis();
String time = mFormatter.format(new Date());
String fileName = "crash-" + time + ".log";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = MicroPhotoContext.buildMasterAppDir(MpMstApplication.getContext()) + "logs/";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
fos.close();
}
return fileName;
} catch (Exception e) {
Log.e(TAG, "an error occured while writing file...", e);
}
return null;
}
}

@ -49,7 +49,7 @@ public class MainActivity extends AppCompatActivity {
// String buildTime = BuildConfig.BUILD_
Date date = new Date(BuildConfig.BUILD_TIMESTAMP);
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
actionBar.setTitle(actionBar.getTitle().toString() + " v" + MicroPhotoContext.getVersionName(getApplicationContext()) + " " + sdf.format(date));
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

@ -0,0 +1,23 @@
package com.xypower.mpmaster;
import android.app.Application;
import android.content.Context;
public class MpMstApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
//初始化-异常捕获(设置该CrashHandler为程序的默认处理器)
CrashHandler unCeHandler = new CrashHandler();
Thread.setDefaultUncaughtExceptionHandler(unCeHandler);
}
public static Context getContext() {
return context;
}
}

@ -1,5 +1,5 @@
<resources>
<string name="app_name">MpMaster</string>
<string name="app_name">运维APP</string>
<string name="text_name_notification">Notification Name</string>
</resources>
Loading…
Cancel
Save