mirror of
http://gitea.winboll.cc/Studio/WinBoLL.git
synced 2026-06-29 03:59:52 +08:00
合并 APPBase 项目
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Wed May 27 14:51:40 HKT 2026
|
#Wed Jun 03 20:17:17 HKT 2026
|
||||||
stageCount=23
|
stageCount=27
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.20
|
baseVersion=15.20
|
||||||
publishVersion=15.20.22
|
publishVersion=15.20.26
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.20.23
|
baseBetaVersion=15.20.27
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package cc.winboll.studio.appbase;
|
package cc.winboll.studio.appbase;
|
||||||
|
|
||||||
|
import cc.winboll.studio.libappbase.CrashActivity;
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.libappbase.ToastUtils;
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
import cc.winboll.studio.libappbase.BuildConfig;
|
import cc.winboll.studio.libappbase.utils.CrashHandleNotifyUtils;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -21,10 +24,24 @@ public class App extends GlobalApplication {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
|
try {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
// 初始化 Toast 工具类(传入应用全局上下文,确保 Toast 可在任意地方调用)
|
// 初始化 Toast 工具类(传入应用全局上下文,确保 Toast 可在任意地方调用)
|
||||||
ToastUtils.init(getApplicationContext());
|
ToastUtils.init(getApplicationContext());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
e.printStackTrace(pw);
|
||||||
|
pw.close();
|
||||||
|
String stackTraceStr = sw.toString();
|
||||||
|
CrashHandleNotifyUtils.handleUncaughtException(
|
||||||
|
this,
|
||||||
|
getPackageName(),
|
||||||
|
stackTraceStr,
|
||||||
|
CrashActivity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Wed May 27 14:51:29 HKT 2026
|
#Wed Jun 03 20:17:02 HKT 2026
|
||||||
stageCount=23
|
stageCount=27
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.20
|
baseVersion=15.20
|
||||||
publishVersion=15.20.22
|
publishVersion=15.20.26
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.20.23
|
baseBetaVersion=15.20.27
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
android:networkSecurityConfig="@xml/network_security_config">
|
android:networkSecurityConfig="@xml/network_security_config">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".CrashHandler$CrashActivity"
|
android:name=".CrashActivity"
|
||||||
android:label="CrashActivity"
|
android:label="CrashActivity"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleInstance"
|
||||||
android:process=":CrashActivity"/>
|
android:process=":CrashActivity"/>
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package cc.winboll.studio.libappbase;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
import android.widget.ScrollView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
public final class CrashActivity extends Activity implements MenuItem.OnMenuItemClickListener {
|
||||||
|
private static final int MENUITEM_COPY = 0;
|
||||||
|
private static final int MENUITEM_RESTART = 1;
|
||||||
|
|
||||||
|
private String mLog;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
AppCrashSafetyWire.getInstance().postResumeCrashSafetyWireHandler(getApplicationContext());
|
||||||
|
mLog = getIntent().getStringExtra(CrashHandler.EXTRA_CRASH_LOG);
|
||||||
|
setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
|
||||||
|
initLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initLayout() {
|
||||||
|
ScrollView contentView = new ScrollView(this);
|
||||||
|
contentView.setFillViewport(true);
|
||||||
|
|
||||||
|
HorizontalScrollView hw = new HorizontalScrollView(this);
|
||||||
|
hw.setBackgroundColor(0xFFF5F5F5);
|
||||||
|
|
||||||
|
TextView message = new TextView(this);
|
||||||
|
final int padding = dp2px(16);
|
||||||
|
message.setPadding(padding, padding, padding, padding);
|
||||||
|
message.setText(mLog);
|
||||||
|
message.setTextColor(0xFF000000);
|
||||||
|
message.setTextIsSelectable(true);
|
||||||
|
|
||||||
|
hw.addView(message);
|
||||||
|
contentView.addView(hw, ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
setContentView(contentView);
|
||||||
|
|
||||||
|
getActionBar().setTitle(CrashHandler.TITTLE);
|
||||||
|
getActionBar().setSubtitle(GlobalApplication.getAppName(getApplicationContext()) + " Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
restartApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restartApp() {
|
||||||
|
final Intent intent = getPackageManager()
|
||||||
|
.getLaunchIntentForPackage(getPackageName());
|
||||||
|
if (intent != null) {
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
| Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
|
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
android.os.Process.killProcess(android.os.Process.myPid());
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int dp2px(final float dpValue) {
|
||||||
|
final float scale = Resources.getSystem().getDisplayMetrics().density;
|
||||||
|
return (int) (dpValue * scale + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
|
menu.add(0, MENUITEM_COPY, 0, "Copy")
|
||||||
|
.setOnMenuItemClickListener(this)
|
||||||
|
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||||
|
|
||||||
|
menu.add(0, MENUITEM_RESTART, 0, "Restart")
|
||||||
|
.setOnMenuItemClickListener(this)
|
||||||
|
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(final MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case MENUITEM_COPY:
|
||||||
|
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), mLog));
|
||||||
|
Toast.makeText(getApplication(), "The text is copied.", Toast.LENGTH_SHORT).show();
|
||||||
|
break;
|
||||||
|
case MENUITEM_RESTART:
|
||||||
|
AppCrashSafetyWire.getInstance().resumeToMaximumImmediately();
|
||||||
|
restartApp();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +1,13 @@
|
|||||||
package cc.winboll.studio.libappbase;
|
package cc.winboll.studio.libappbase;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.HorizontalScrollView;
|
|
||||||
import android.widget.ScrollView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import cc.winboll.studio.libappbase.utils.CrashHandleNotifyUtils;
|
import cc.winboll.studio.libappbase.utils.CrashHandleNotifyUtils;
|
||||||
|
|
||||||
@@ -220,111 +206,5 @@ public final class CrashHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================== 内部Activity页面 ======================
|
|
||||||
/**
|
|
||||||
* 基础极简崩溃页面
|
|
||||||
* 保险丝熔断时启动,避免复杂布局二次崩溃
|
|
||||||
*/
|
|
||||||
public static final class CrashActivity extends Activity implements MenuItem.OnMenuItemClickListener {
|
|
||||||
private static final int MENUITEM_COPY = 0;
|
|
||||||
private static final int MENUITEM_RESTART = 1;
|
|
||||||
|
|
||||||
private String mLog;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
AppCrashSafetyWire.getInstance().postResumeCrashSafetyWireHandler(getApplicationContext());
|
|
||||||
mLog = getIntent().getStringExtra(EXTRA_CRASH_LOG);
|
|
||||||
setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
|
|
||||||
initLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态初始化布局
|
|
||||||
*/
|
|
||||||
private void initLayout() {
|
|
||||||
ScrollView contentView = new ScrollView(this);
|
|
||||||
contentView.setFillViewport(true);
|
|
||||||
|
|
||||||
HorizontalScrollView hw = new HorizontalScrollView(this);
|
|
||||||
hw.setBackgroundColor(0xFFF5F5F5);
|
|
||||||
|
|
||||||
TextView message = new TextView(this);
|
|
||||||
final int padding = dp2px(16);
|
|
||||||
message.setPadding(padding, padding, padding, padding);
|
|
||||||
message.setText(mLog);
|
|
||||||
message.setTextColor(0xFF000000);
|
|
||||||
message.setTextIsSelectable(true);
|
|
||||||
|
|
||||||
hw.addView(message);
|
|
||||||
contentView.addView(hw, ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
|
||||||
setContentView(contentView);
|
|
||||||
|
|
||||||
getActionBar().setTitle(TITTLE);
|
|
||||||
getActionBar().setSubtitle(GlobalApplication.class.getSimpleName() + " Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
restartApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重启应用
|
|
||||||
*/
|
|
||||||
private void restartApp() {
|
|
||||||
final Intent intent = getPackageManager()
|
|
||||||
.getLaunchIntentForPackage(getPackageName());
|
|
||||||
if (intent != null) {
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP
|
|
||||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
finish();
|
|
||||||
android.os.Process.killProcess(android.os.Process.myPid());
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dp转px
|
|
||||||
*/
|
|
||||||
private int dp2px(final float dpValue) {
|
|
||||||
final float scale = Resources.getSystem().getDisplayMetrics().density;
|
|
||||||
return (int) (dpValue * scale + 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(final Menu menu) {
|
|
||||||
menu.add(0, MENUITEM_COPY, 0, "Copy")
|
|
||||||
.setOnMenuItemClickListener(this)
|
|
||||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
|
||||||
|
|
||||||
menu.add(0, MENUITEM_RESTART, 0, "Restart")
|
|
||||||
.setOnMenuItemClickListener(this)
|
|
||||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemClick(final MenuItem item) {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case MENUITEM_COPY:
|
|
||||||
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
|
||||||
cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), mLog));
|
|
||||||
Toast.makeText(getApplication(), "The text is copied.", Toast.LENGTH_SHORT).show();
|
|
||||||
break;
|
|
||||||
case MENUITEM_RESTART:
|
|
||||||
AppCrashSafetyWire.getInstance().resumeToMaximumImmediately();
|
|
||||||
restartApp();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import android.content.SharedPreferences;
|
|||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.util.Log;
|
||||||
|
import cc.winboll.studio.libappbase.utils.CrashHandleNotifyUtils;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||||
@@ -125,7 +129,9 @@ public class GlobalApplication extends Application {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
|
try {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
// 初始化单例实例(确保在所有初始化操作前完成)
|
// 初始化单例实例(确保在所有初始化操作前完成)
|
||||||
sInstance = this;
|
sInstance = this;
|
||||||
|
|
||||||
@@ -136,6 +142,19 @@ public class GlobalApplication extends Application {
|
|||||||
initWinbollHost();
|
initWinbollHost();
|
||||||
|
|
||||||
LogUtils.d(TAG, "GlobalApplication 初始化完成,单例实例已创建");
|
LogUtils.d(TAG, "GlobalApplication 初始化完成,单例实例已创建");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
e.printStackTrace(pw);
|
||||||
|
pw.close();
|
||||||
|
String stackTraceStr = sw.toString();
|
||||||
|
CrashHandleNotifyUtils.handleUncaughtException(
|
||||||
|
this,
|
||||||
|
getPackageName(),
|
||||||
|
stackTraceStr,
|
||||||
|
CrashActivity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,7 +209,7 @@ public class GlobalApplication extends Application {
|
|||||||
*/
|
*/
|
||||||
public static String getAppName(Context context) {
|
public static String getAppName(Context context) {
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
LogUtils.w(TAG, "getAppName: 上下文为空,返回 null");
|
Log.w(TAG, "getAppName: 上下文为空,返回 null");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
PackageManager packageManager = context.getPackageManager();
|
PackageManager packageManager = context.getPackageManager();
|
||||||
@@ -206,8 +225,7 @@ public class GlobalApplication extends Application {
|
|||||||
return appName;
|
return appName;
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
// 包名不存在(理论上不会发生,捕获异常避免崩溃)
|
// 包名不存在(理论上不会发生,捕获异常避免崩溃)
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
Log.e(TAG, "获取应用名称失败:包名不存在", e);
|
||||||
//LogUtils.e(TAG, "获取应用名称失败:包名不存在", e);
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public final class GlobalCrashActivity extends Activity implements MenuItem.OnMe
|
|||||||
mCrashLog = getIntent().getStringExtra(CrashHandler.EXTRA_CRASH_LOG);
|
mCrashLog = getIntent().getStringExtra(CrashHandler.EXTRA_CRASH_LOG);
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
intent.putExtra(CrashHandler.EXTRA_CRASH_LOG, mCrashLog);
|
intent.putExtra(CrashHandler.EXTRA_CRASH_LOG, mCrashLog);
|
||||||
CrashHandleNotifyUtils.handleUncaughtException(GlobalApplication.getInstance(), intent, CrashHandler.CrashActivity.class);
|
CrashHandleNotifyUtils.handleUncaughtException(GlobalApplication.getInstance(), intent, CrashActivity.class);
|
||||||
|
|
||||||
StackTraceElement[] stackElements = Thread.currentThread().getStackTrace();
|
StackTraceElement[] stackElements = Thread.currentThread().getStackTrace();
|
||||||
StringBuilder sb = new StringBuilder("GlobalCrashActivity onCreate StackTrace");
|
StringBuilder sb = new StringBuilder("GlobalCrashActivity onCreate StackTrace");
|
||||||
|
|||||||
Reference in New Issue
Block a user