feat: 应用初始化模块 - 崩溃恢复与时间更新
新增: - CrashHandler 崩溃日志记录+杀进程(系统自动重启Launcher) 修改: - WatchApplication 注册 CrashHandler - NavBarHelper 新增 updateTime() 方法 - HomeFragment 添加每秒时间更新定时器 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
37
app/src/main/java/com/xiaoqu/watch/app/CrashHandler.kt
Normal file
37
app/src/main/java/com/xiaoqu/watch/app/CrashHandler.kt
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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<FragmentHomeBinding>() {
|
||||
// 绑定测试按钮
|
||||
setupButtons()
|
||||
|
||||
// 启动时间更新定时器(每秒刷新 NavBar 时间)
|
||||
startTimeUpdater()
|
||||
|
||||
// 监听系统状态事件
|
||||
observeSystemEvents()
|
||||
}
|
||||
@@ -173,6 +178,16 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
/** 每秒更新 NavBar 时间显示,跟随 Fragment 生命周期自动取消 */
|
||||
private fun startTimeUpdater() {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
while (isActive) {
|
||||
NavBarHelper.updateTime(binding.root)
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 监听系统状态事件(电量、蓝牙)<E78999><EFBC89><EFBFBD>更新 NavBar 和状态显示 */
|
||||
private fun observeSystemEvents() {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
|
||||
@@ -103,6 +103,14 @@ object NavBarHelper {
|
||||
))
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新时间显示(首页模式下每秒调用)
|
||||
* @param rootView 包含 layout_nav_bar 的根视图
|
||||
*/
|
||||
fun updateTime(rootView: View) {
|
||||
rootView.findViewById<TextView>(R.id.navTitle)?.text = DateUtil.formatTimeShort()
|
||||
}
|
||||
|
||||
/** 为 TextView 设置 iconfont 字体 */
|
||||
private fun applyIconFont(rootView: View, viewId: Int, typeface: Typeface) {
|
||||
rootView.findViewById<TextView>(viewId)?.typeface = typeface
|
||||
|
||||
Reference in New Issue
Block a user