应用保险丝熔断测试通过

This commit is contained in:
ZhanGSKen 2025-02-08 12:26:59 +08:00
parent 26fcd9b584
commit a72c5e1e6e
3 changed files with 102 additions and 44 deletions

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Fri Feb 07 11:37:57 GMT 2025 #Sat Feb 08 04:25:51 GMT 2025
stageCount=1 stageCount=1
libraryProject=libappbase libraryProject=libappbase
baseVersion=1.2 baseVersion=1.2
publishVersion=1.2.0 publishVersion=1.2.0
buildCount=180 buildCount=222
baseBetaVersion=1.2.1 baseBetaVersion=1.2.1

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Fri Feb 07 11:37:57 GMT 2025 #Sat Feb 08 04:25:51 GMT 2025
stageCount=1 stageCount=1
libraryProject=libappbase libraryProject=libappbase
baseVersion=1.2 baseVersion=1.2
publishVersion=1.2.0 publishVersion=1.2.0
buildCount=180 buildCount=222
baseBetaVersion=1.2.1 baseBetaVersion=1.2.1

View File

@ -29,7 +29,6 @@ import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import cc.winboll.studio.libappbase.GlobalApplication;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -44,6 +43,7 @@ import java.util.Date;
import java.util.Locale; import java.util.Locale;
public final class CrashHandler { public final class CrashHandler {
public static final String TAG = "CrashHandler"; public static final String TAG = "CrashHandler";
final static String PREFS = CrashHandler.class.getName() + "PREFS"; final static String PREFS = CrashHandler.class.getName() + "PREFS";
@ -53,13 +53,10 @@ public final class CrashHandler {
public static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler(); public static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler();
public static void init(Application app) { public static void init(Application app) {
_CrashCountFilePath = app.getExternalFilesDir("CrashHandler") + "/IsCrashHandlerCrashHappen.dat"; _CrashCountFilePath = app.getExternalFilesDir("CrashHandler") + "/IsCrashHandlerCrashHappen.dat";
LogUtils.d(TAG, String.format("_CrashCountFilePath %s", _CrashCountFilePath));
init(app, null); init(app, null);
LogUtils.d(TAG, "init");
} }
public static void init(final Application app, final String crashDir) { public static void init(final Application app, final String crashDir) {
@ -77,6 +74,9 @@ public final class CrashHandler {
} }
private void tryUncaughtException(Thread thread, Throwable throwable) { private void tryUncaughtException(Thread thread, Throwable throwable) {
// 每到这里就燃烧一次保险丝
AppCrashSafetyWire.getInstance().burnSafetyWire();
final String time = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss", Locale.getDefault()).format(new Date()); final String time = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss", Locale.getDefault()).format(new Date());
File crashFile = new File(TextUtils.isEmpty(crashDir) ? new File(app.getExternalFilesDir(null), "crash") File crashFile = new File(TextUtils.isEmpty(crashDir) ? new File(app.getExternalFilesDir(null), "crash")
: new File(crashDir), "crash_" + time + ".txt"); : new File(crashDir), "crash_" + time + ".txt");
@ -107,8 +107,6 @@ public final class CrashHandler {
sb.append("Android SDK : ").append(Build.VERSION.SDK_INT).append("\n"); sb.append("Android SDK : ").append(Build.VERSION.SDK_INT).append("\n");
sb.append("App VersionName : ").append(versionName).append("\n"); sb.append("App VersionName : ").append(versionName).append("\n");
sb.append("App VersionCode : ").append(versionCode).append("\n"); sb.append("App VersionCode : ").append(versionCode).append("\n");
sb.append("AppBase GlobalApplication Debug Mode : ").append(GlobalApplication.isDebuging).append("\n");
sb.append("CrashHandler CurrentSafeLevel : ").append(String.format("%d", AppCrashSafetyWire.getInstance().getCurrentSafetyLevel())).append("\n");
sb.append("************* Crash Head ****************\n"); sb.append("************* Crash Head ****************\n");
sb.append("\n").append(fullStackTrace); sb.append("\n").append(fullStackTrace);
@ -120,16 +118,18 @@ public final class CrashHandler {
gotoCrashActiviy: { gotoCrashActiviy: {
Intent intent = new Intent(); Intent intent = new Intent();
LogUtils.d(TAG, "gotoCrashActiviy: ");
if (AppCrashSafetyWire.getInstance().isAppCrashSafetyWireOK() && AppCrashSafetyWire.getInstance().postCrashSafetyWire(app)) { if (AppCrashSafetyWire.getInstance().isAppCrashSafetyWireOK()) {
AppCrashSafetyWire.getInstance().reset(); LogUtils.d(TAG, "gotoCrashActiviy: isAppCrashSafetyWireOK");
//AppCrashSafetyWire.getInstance().postCrashSafetyWire(app);
intent.setClass(app, GlobalCrashActiviy.class); intent.setClass(app, GlobalCrashActiviy.class);
intent.putExtra(GlobalCrashActiviy.EXTRA_CRASH_INFO, errorLog); intent.putExtra(GlobalCrashActiviy.EXTRA_CRASH_INFO, errorLog);
// 如果发生了 CrashHandler 内部崩溃 就调用基础的应用崩溃显示类 // 如果发生了 CrashHandler 内部崩溃 就调用基础的应用崩溃显示类
// intent.setClass(app, GlobalCrashActiviy.class); // intent.setClass(app, GlobalCrashActiviy.class);
// intent.putExtra(GlobalCrashActiviy.EXTRA_CRASH_INFO, errorLog); // intent.putExtra(GlobalCrashActiviy.EXTRA_CRASH_INFO, errorLog);
} else { } else {
AppCrashSafetyWire.getInstance().reset(); LogUtils.d(TAG, "gotoCrashActiviy: else");
AppCrashSafetyWire.getInstance().resumeToMaximumImmediately();
// 正常状态调用进阶的应用崩溃显示页 // 正常状态调用进阶的应用崩溃显示页
intent.setClass(app, CrashActiviy.class); intent.setClass(app, CrashActiviy.class);
intent.putExtra(CrashActiviy.EXTRA_CRASH_INFO, errorLog); intent.putExtra(CrashActiviy.EXTRA_CRASH_INFO, errorLog);
@ -184,11 +184,12 @@ public final class CrashHandler {
volatile static AppCrashSafetyWire _AppCrashSafetyWire; volatile static AppCrashSafetyWire _AppCrashSafetyWire;
volatile int currentSafetyLevel; // 熔断值 0 表示熔断了 volatile Integer currentSafetyLevel; // 熔断值 0 表示熔断了
private static final int _MINI = 1; private static final int _MINI = 1;
private static final int _MAX = 5; private static final int _MAX = 2;
AppCrashSafetyWire() { AppCrashSafetyWire() {
LogUtils.d(TAG, "AppCrashSafetyWire()");
currentSafetyLevel = loadCurrentSafetyLevel(); currentSafetyLevel = loadCurrentSafetyLevel();
} }
@ -208,79 +209,136 @@ public final class CrashHandler {
} }
public void saveCurrentSafetyLevel(int currentSafetyLevel) { public void saveCurrentSafetyLevel(int currentSafetyLevel) {
LogUtils.d(TAG, "saveCurrentSafetyLevel()");
this.currentSafetyLevel = currentSafetyLevel; this.currentSafetyLevel = currentSafetyLevel;
try { try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(_CrashCountFilePath)); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(_CrashCountFilePath));
oos.writeInt(currentSafetyLevel); oos.writeInt(currentSafetyLevel);
oos.flush();
oos.close();
LogUtils.d(TAG, String.format("saveCurrentSafetyLevel writeInt currentSafetyLevel %d", currentSafetyLevel));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
} }
} }
public int loadCurrentSafetyLevel() { public int loadCurrentSafetyLevel() {
LogUtils.d(TAG, "loadCurrentSafetyLevel()");
try { try {
File f = new File(_CrashCountFilePath); File f = new File(_CrashCountFilePath);
if (f.exists()) { if (f.exists()) {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(_CrashCountFilePath)); ObjectInputStream ois = new ObjectInputStream(new FileInputStream(_CrashCountFilePath));
currentSafetyLevel = ois.readInt(); currentSafetyLevel = ois.readInt();
LogUtils.d(TAG, String.format("loadCurrentSafetyLevel() readInt currentSafetyLevel %d", currentSafetyLevel));
} else { } else {
currentSafetyLevel = _MAX; currentSafetyLevel = _MAX;
LogUtils.d(TAG, String.format("loadCurrentSafetyLevel() currentSafetyLevel init to _MAX->%d", _MAX));
saveCurrentSafetyLevel(currentSafetyLevel); saveCurrentSafetyLevel(currentSafetyLevel);
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
} }
return currentSafetyLevel; return currentSafetyLevel;
} }
boolean putOnSafetyWire() { boolean burnSafetyWire() {
LogUtils.d(TAG, "burnSafetyWire()");
// 崩溃计数进入崩溃保险值 // 崩溃计数进入崩溃保险值
int safeLevel = loadCurrentSafetyLevel(); int safeLevel = loadCurrentSafetyLevel();
if (isSafetyWireOK(safeLevel)) { if (isSafetyWireWorking(safeLevel)) {
// 如果保险丝未熔断, 就减少一次熔断值 // 如果保险丝未熔断, 就增加一次熔断值
LogUtils.d(TAG, "burnSafetyWire() use");
saveCurrentSafetyLevel(safeLevel - 1); saveCurrentSafetyLevel(safeLevel - 1);
return true; return isSafetyWireWorking(safeLevel - 1);
} }
return false; return false;
} }
boolean isSafetyWireOK(int safetyLevel) { boolean resumeSafetyLevel() {
LogUtils.d(TAG, "resumeSafetyLevel()");
// 崩溃计数进入崩溃保险值
int safeLevel = loadCurrentSafetyLevel();
if (isSafetyWireWorking(safeLevel)) {
// 如果保险丝未熔断, 就增加一次熔断值
LogUtils.d(TAG, "resumeSafetyLevel() resume 1");
saveCurrentSafetyLevel(safeLevel + 1);
return isSafetyWireWorking(safeLevel + 1);
} else {
LogUtils.d(TAG, "resumeSafetyLevel() resume immediately");
resumeToMaximumImmediately();
}
return false;
}
boolean isSafetyWireWorking(int safetyLevel) {
LogUtils.d(TAG, "isSafetyWireOK()");
//safetyLevel = _MINI;
//safetyLevel = _MINI - 1;
//safetyLevel = _MINI + 1;
//safetyLevel = _MAX;
//safetyLevel = _MAX + 1;
LogUtils.d(TAG, String.format("SafetyLevel %d", safetyLevel));
if (safetyLevel >= _MINI && safetyLevel <= _MAX) { if (safetyLevel >= _MINI && safetyLevel <= _MAX) {
// 如果在保险值之内 // 如果在保险值之内
LogUtils.d(TAG, String.format("In Safety Level"));
return true; return true;
} }
LogUtils.d(TAG, String.format("Out of Safety Level"));
return false; return false;
} }
void reset() { void resumeToMaximumImmediately() {
saveCurrentSafetyLevel(_MAX); LogUtils.d(TAG, "resumeToMaximumImmediately() call saveCurrentSafetyLevel(_MAX)");
AppCrashSafetyWire.getInstance().saveCurrentSafetyLevel(_MAX);
} }
// boolean resumeToMaximum(int safetyLevel) {
// if (safetyLevel + 1 < _MAX
// && safetyLevel >= _MINI
// && isSafetyWireWorking(safetyLevel + 1)) {
// AppCrashSafetyWire.getInstance().saveCurrentSafetyLevel(currentSafetyLevel + 1);
// return true;
// }
// return false;
// }
void off() { void off() {
LogUtils.d(TAG, "off()");
saveCurrentSafetyLevel(_MINI); saveCurrentSafetyLevel(_MINI);
} }
boolean isAppCrashSafetyWireOK() { boolean isAppCrashSafetyWireOK() {
return false; LogUtils.d(TAG, "isAppCrashSafetyWireOK()");
currentSafetyLevel = loadCurrentSafetyLevel();
return isSafetyWireWorking(currentSafetyLevel);
} }
// 调用函数以启用持续崩溃保险从而调用 CrashHandler 内部崩溃处理窗口 // 调用函数以启用持续崩溃保险从而调用 CrashHandler 内部崩溃处理窗口
boolean postCrashSafetyWire(final Context context) { // boolean postCrashSafetyWire(final Context context) {
if (AppCrashSafetyWire.getInstance().putOnSafetyWire()) { // LogUtils.d(TAG, "postCrashSafetyWire()");
// 设置内部崩溃处理模块失效 // if (AppCrashSafetyWire.getInstance().isAppCrashSafetyWireOK()) {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable(){ // // 保险丝在工作连接状态
@Override // // 设置内部崩溃处理模块失效
public void run() { // new Handler(Looper.getMainLooper()).postDelayed(new Runnable(){
// 进程持续运行时重置保险丝 // @Override
//AppCrashSafetyWire.getInstance().reset(); // public void run() {
} // // 进程持续运行时恢复保险丝熔断值
}, 1000); // //Resume to maximum
return true; // LogUtils.d(TAG, "postCrashSafetyWire Resume to maximum");
} // while (resumeToMaximum(currentSafetyLevel + 1)) {
return false; // try {
} // Thread.sleep(1000);
// } catch (InterruptedException e) {
// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
// }
// }
// }
// }, 10000);
// return true;
// }
// return false;
// }
} }