diff --git a/appbase/build.properties b/appbase/build.properties
index b824b053..a7e41487 100644
--- a/appbase/build.properties
+++ b/appbase/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Tue Nov 11 12:40:49 GMT 2025
+#Tue Nov 11 13:06:53 GMT 2025
stageCount=10
libraryProject=libappbase
baseVersion=15.10
publishVersion=15.10.9
-buildCount=5
+buildCount=8
baseBetaVersion=15.10.10
diff --git a/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java b/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java
index 0a45ba63..b3ec737a 100644
--- a/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java
+++ b/appbase/src/main/java/cc/winboll/studio/appbase/MainActivity.java
@@ -8,10 +8,10 @@ import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.widget.Toast;
import android.widget.Toolbar;
import cc.winboll.studio.appbase.R;
import cc.winboll.studio.libappbase.LogActivity;
+import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.ToastUtils;
public class MainActivity extends Activity {
@@ -56,6 +56,13 @@ public class MainActivity extends Activity {
public void onLogTest(View view) {
LogActivity.startLogActivity(this);
}
+
+ public void onToastUtilsTest(View view) {
+ LogUtils.d(TAG, "onToastUtilsTest");
+ ToastUtils.init(getApplicationContext());
+ ToastUtils.show("Hello, WinBoLL!");
+ ToastUtils.release();
+ }
/**
* 唤起默认浏览器打开指定网站
diff --git a/appbase/src/main/res/layout/activity_main.xml b/appbase/src/main/res/layout/activity_main.xml
index 9552e3ad..bd6a3e43 100644
--- a/appbase/src/main/res/layout/activity_main.xml
+++ b/appbase/src/main/res/layout/activity_main.xml
@@ -28,7 +28,8 @@
android:background="#81C7F5"
android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp"
- android:onClick="onCrashTest"/>
+ android:onClick="onCrashTest"
+ android:layout_margin="10dp"/>
+ android:onClick="onLogTest"
+ android:layout_margin="10dp"/>
+
+
diff --git a/libappbase/build.properties b/libappbase/build.properties
index b824b053..a7e41487 100644
--- a/libappbase/build.properties
+++ b/libappbase/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Tue Nov 11 12:40:49 GMT 2025
+#Tue Nov 11 13:06:53 GMT 2025
stageCount=10
libraryProject=libappbase
baseVersion=15.10
publishVersion=15.10.9
-buildCount=5
+buildCount=8
baseBetaVersion=15.10.10
diff --git a/libappbase/src/main/java/cc/winboll/studio/libappbase/ToastUtils.java b/libappbase/src/main/java/cc/winboll/studio/libappbase/ToastUtils.java
index a22f2639..5783e8ee 100644
--- a/libappbase/src/main/java/cc/winboll/studio/libappbase/ToastUtils.java
+++ b/libappbase/src/main/java/cc/winboll/studio/libappbase/ToastUtils.java
@@ -1,34 +1,135 @@
package cc.winboll.studio.libappbase;
/**
- * @Author ZhanGSKen
- * @Date 2025/03/12 12:02:31
+ * @Author ZhanGSKen&豆包大模型
+ * @Date 2025/11/11 20:51
+ * @Describe 吐司工具类(单例模式)
+ * 简化 Android 吐司的创建与展示,通过 Handler 确保主线程显示,统一管理上下文,避免内存泄漏
*/
import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.widget.Toast;
public class ToastUtils {
+ /** 工具类日志 TAG(用于调试输出) */
public static final String TAG = "ToastUtils";
+ /** 消息标识:显示短时长吐司 */
+ private static final int MSG_SHOW_SHORT_TOAST = 1001;
- volatile static ToastUtils _ToastUtils;
- Context mContext;
+ /** 单例实例(volatile 保证多线程下可见性,避免指令重排) */
+ private static volatile ToastUtils sInstance;
+ /** 全局上下文(建议传入 Application 实例,避免内存泄漏) */
+ private Context mContext;
+ /** 主线程 Handler(用于接收并处理吐司显示消息,确保 UI 操作在主线程) */
+ private static Handler _mMainHandler;
- ToastUtils() {
+ /**
+ * 私有构造方法(禁止外部直接创建实例,确保单例)
+ * 初始化主线程 Handler,绑定主线程 Looper
+ */
+ private ToastUtils() {
+ // 初始化 Handler,绑定主线程 Looper(确保吐司在主线程显示)
+ _mMainHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ // 处理消息:显示吐司
+ if (msg.what == MSG_SHOW_SHORT_TOAST && msg.obj != null) {
+ String message = (String) msg.obj;
+ showToastInternal(message);
+ }
+ }
+ };
}
- synchronized static ToastUtils getInstance() {
- if (_ToastUtils == null) {
- _ToastUtils = new ToastUtils();
+ /**
+ * 获取单例实例(双重检查锁定,高效且线程安全)
+ * @return ToastUtils 单例对象
+ */
+ private static ToastUtils getInstance() {
+ if (sInstance == null) { // 第一次检查(无锁,提升效率)
+ synchronized (ToastUtils.class) { // 加锁,确保线程安全
+ if (sInstance == null) { // 第二次检查(避免多线程并发创建多个实例)
+ sInstance = new ToastUtils();
+ }
+ }
}
- return _ToastUtils;
+ return sInstance;
}
+ /**
+ * 初始化工具类(必须在 Application 或 Activity 启动时调用)
+ * 传入全局上下文,用于创建 Toast 实例
+ * @param context 全局上下文(推荐传入 getApplicationContext())
+ */
public static void init(Context context) {
- getInstance().mContext = context;
+ if (context == null) {
+ throw new IllegalArgumentException("初始化上下文不能为 null!");
+ }
+ // 初始化全局上下文(使用 Application 上下文,避免内存泄漏)
+ getInstance().mContext = context.getApplicationContext();
}
+ /**
+ * 外部接口:显示短时长吐司(默认显示 2 秒)
+ * 接收外部消息参数,通过 Handler 发送消息到主线程
+ * @param message 吐司展示的文本内容(非空)
+ */
public static void show(String message) {
- Toast.makeText(getInstance().mContext, message, Toast.LENGTH_SHORT).show();
+ if (message == null || message.isEmpty()) {
+ return; // 空消息直接返回,避免无效显示
+ }
+ // 校验工具类是否初始化
+ if (getInstance().mContext == null) {
+ throw new IllegalStateException("ToastUtils 未初始化!请先调用 init(Context) 方法");
+ }
+ // 发送消息到主线程 Handler
+ getInstance().sendToastMessage(message);
+ }
+
+ /**
+ * 内部私有方法:发送吐司消息(通过 Handler 传递)
+ * 使用实例初始化时的全局上下文确保消息发送有效性
+ * @param message 吐司文本内容
+ */
+ private void sendToastMessage(String message) {
+ // 校验 Handler 和上下文是否有效
+ if (_mMainHandler == null || mContext == null) {
+ return;
+ }
+ // 创建消息对象,携带吐司内容
+ Message msg = _mMainHandler.obtainMessage(MSG_SHOW_SHORT_TOAST);
+ msg.obj = message;
+ // 发送消息(放入主线程消息队列)
+ _mMainHandler.sendMessage(msg);
+ }
+
+ /**
+ * 内部私有方法:实际显示吐司(运行在主线程)
+ * @param message 吐司文本内容
+ */
+ private void showToastInternal(String message) {
+ // 校验上下文有效性
+ if (mContext == null) {
+ return;
+ }
+ // 显示短时长吐司
+ Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
+ }
+
+ /**
+ * 可选:释放资源(如在应用退出时调用)
+ * 移除 Handler 未处理的消息,避免内存泄漏
+ */
+ public static void release() {
+ if (getInstance()._mMainHandler != null) {
+ _mMainHandler.removeCallbacksAndMessages(null); // 移除所有未处理消息
+ _mMainHandler = null;
+ }
+ sInstance = null; // 销毁单例实例
}
}
+