From fb884ea81652c28c36c7245f92437c00bd16e1c6 Mon Sep 17 00:00:00 2001 From: dongliang Date: Mon, 27 Apr 2026 14:56:23 +0930 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BA=94=E7=94=A8=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E6=A8=A1=E5=9D=97=20-=20=E5=B4=A9=E6=BA=83=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E4=B8=8E=E6=97=B6=E9=97=B4=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增: - CrashHandler 崩溃日志记录+杀进程(系统自动重启Launcher) 修改: - WatchApplication 注册 CrashHandler - NavBarHelper 新增 updateTime() 方法 - HomeFragment 添加每秒时间更新定时器 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../java/com/xiaoqu/watch/app/CrashHandler.kt | 37 +++++++++++++++++++ .../com/xiaoqu/watch/app/WatchApplication.kt | 20 +++++----- .../com/xiaoqu/watch/ui/home/HomeFragment.kt | 15 ++++++++ .../xiaoqu/watch/ui/widget/NavBarHelper.kt | 8 ++++ 4 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/xiaoqu/watch/app/CrashHandler.kt diff --git a/app/src/main/java/com/xiaoqu/watch/app/CrashHandler.kt b/app/src/main/java/com/xiaoqu/watch/app/CrashHandler.kt new file mode 100644 index 0000000..ff358b6 --- /dev/null +++ b/app/src/main/java/com/xiaoqu/watch/app/CrashHandler.kt @@ -0,0 +1,37 @@ +package com.xiaoqu.watch.app + +import android.content.Context +import timber.log.Timber +import kotlin.system.exitProcess + +/** + * 全局崩溃处理器 + * 捕获未处理的异常,记录崩溃日志后杀进程 + * Launcher 模式下系统会自动重启应用,无需主动设置重启 + * + * 注册时机:WatchApplication.onCreate + */ +class CrashHandler(private val context: Context) : Thread.UncaughtExceptionHandler { + + /** 系统默认的异常处理器(备用) */ + private val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() + + /** 注册为全局异常处理器 */ + fun init() { + Thread.setDefaultUncaughtExceptionHandler(this) + Timber.d("CrashHandler 已注册") + } + + /** + * 处理未捕获的异常 + * 1. 记录崩溃日志(Timber) + * 2. 杀进程,让系统自动重启 Launcher + */ + override fun uncaughtException(thread: Thread, throwable: Throwable) { + Timber.e(throwable, "应用崩溃 [线程: ${thread.name}]") + + // 杀进程,系统检测到 Launcher 退出后会自动重启 + android.os.Process.killProcess(android.os.Process.myPid()) + exitProcess(1) + } +} diff --git a/app/src/main/java/com/xiaoqu/watch/app/WatchApplication.kt b/app/src/main/java/com/xiaoqu/watch/app/WatchApplication.kt index 5be2342..1de0be5 100644 --- a/app/src/main/java/com/xiaoqu/watch/app/WatchApplication.kt +++ b/app/src/main/java/com/xiaoqu/watch/app/WatchApplication.kt @@ -4,23 +4,25 @@ import android.app.Application import dagger.hilt.android.HiltAndroidApp import timber.log.Timber +/** + * 应用入口(@HiltAndroidApp 触发 Hilt 代码生成) + * + * 初始化序列(必须保持 < 500ms): + * 1. Timber 日志 + * 2. CrashHandler 崩溃恢复 + * 其他初始化延迟到 MainActivity/HomeFragment + */ @HiltAndroidApp class WatchApplication : Application() { override fun onCreate() { super.onCreate() - // 1. Timber 初始化 + // 1. Timber 日志初始化 Timber.plant(Timber.DebugTree()) - // 2-9 其他初始化在后续模块中逐步添加 - // LogManager.init() - // CrashHandler.init() - // DeviceRepository.collectDeviceInfo() - // DeviceMonitor.start() - // ClockManager.start() - // WakeLockHelper.acquire() - // OtaManager.checkOnStartup() + // 2. 崩溃处理器(记录日志 + 杀进程,系统自动重启 Launcher) + CrashHandler(this).init() Timber.d("WatchApplication initialized") } diff --git a/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt b/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt index e4c93af..bdae4a1 100644 --- a/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/xiaoqu/watch/ui/home/HomeFragment.kt @@ -23,6 +23,8 @@ import com.xiaoqu.watch.util.DateUtil import com.xiaoqu.watch.util.DeviceUtil import com.xiaoqu.watch.util.NetworkUtil import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import javax.inject.Inject @@ -73,6 +75,9 @@ class HomeFragment : BaseFragment() { // 绑定测试按钮 setupButtons() + // 启动时间更新定时器(每秒刷新 NavBar 时间) + startTimeUpdater() + // 监听系统状态事件 observeSystemEvents() } @@ -173,6 +178,16 @@ class HomeFragment : BaseFragment() { } } + /** 每秒更新 NavBar 时间显示,跟随 Fragment 生命周期自动取消 */ + private fun startTimeUpdater() { + viewLifecycleOwner.lifecycleScope.launch { + while (isActive) { + NavBarHelper.updateTime(binding.root) + delay(1000) + } + } + } + /** 监听系统状态事件(电量、蓝牙)���更新 NavBar 和状态显示 */ private fun observeSystemEvents() { viewLifecycleOwner.lifecycleScope.launch { diff --git a/app/src/main/java/com/xiaoqu/watch/ui/widget/NavBarHelper.kt b/app/src/main/java/com/xiaoqu/watch/ui/widget/NavBarHelper.kt index 5ad2835..c32609b 100644 --- a/app/src/main/java/com/xiaoqu/watch/ui/widget/NavBarHelper.kt +++ b/app/src/main/java/com/xiaoqu/watch/ui/widget/NavBarHelper.kt @@ -103,6 +103,14 @@ object NavBarHelper { )) } + /** + * 更新时间显示(首页模式下每秒调用) + * @param rootView 包含 layout_nav_bar 的根视图 + */ + fun updateTime(rootView: View) { + rootView.findViewById(R.id.navTitle)?.text = DateUtil.formatTimeShort() + } + /** 为 TextView 设置 iconfont 字体 */ private fun applyIconFont(rootView: View, viewId: Int, typeface: Typeface) { rootView.findViewById(viewId)?.typeface = typeface