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 dagger.hilt.android.HiltAndroidApp
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用入口(@HiltAndroidApp 触发 Hilt 代码生成)
|
||||||
|
*
|
||||||
|
* 初始化序列(必须保持 < 500ms):
|
||||||
|
* 1. Timber 日志
|
||||||
|
* 2. CrashHandler 崩溃恢复
|
||||||
|
* 其他初始化延迟到 MainActivity/HomeFragment
|
||||||
|
*/
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class WatchApplication : Application() {
|
class WatchApplication : Application() {
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
// 1. Timber 初始化
|
// 1. Timber 日志初始化
|
||||||
Timber.plant(Timber.DebugTree())
|
Timber.plant(Timber.DebugTree())
|
||||||
|
|
||||||
// 2-9 其他初始化在后续模块中逐步添加
|
// 2. 崩溃处理器(记录日志 + 杀进程,系统自动重启 Launcher)
|
||||||
// LogManager.init()
|
CrashHandler(this).init()
|
||||||
// CrashHandler.init()
|
|
||||||
// DeviceRepository.collectDeviceInfo()
|
|
||||||
// DeviceMonitor.start()
|
|
||||||
// ClockManager.start()
|
|
||||||
// WakeLockHelper.acquire()
|
|
||||||
// OtaManager.checkOnStartup()
|
|
||||||
|
|
||||||
Timber.d("WatchApplication initialized")
|
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.DeviceUtil
|
||||||
import com.xiaoqu.watch.util.NetworkUtil
|
import com.xiaoqu.watch.util.NetworkUtil
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -73,6 +75,9 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||||||
// 绑定测试按钮
|
// 绑定测试按钮
|
||||||
setupButtons()
|
setupButtons()
|
||||||
|
|
||||||
|
// 启动时间更新定时器(每秒刷新 NavBar 时间)
|
||||||
|
startTimeUpdater()
|
||||||
|
|
||||||
// 监听系统状态事件
|
// 监听系统状态事件
|
||||||
observeSystemEvents()
|
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 和状态显示 */
|
/** 监听系统状态事件(电量、蓝牙)<E78999><EFBC89><EFBFBD>更新 NavBar 和状态显示 */
|
||||||
private fun observeSystemEvents() {
|
private fun observeSystemEvents() {
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
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 字体 */
|
/** 为 TextView 设置 iconfont 字体 */
|
||||||
private fun applyIconFont(rootView: View, viewId: Int, typeface: Typeface) {
|
private fun applyIconFont(rootView: View, viewId: Int, typeface: Typeface) {
|
||||||
rootView.findViewById<TextView>(viewId)?.typeface = typeface
|
rootView.findViewById<TextView>(viewId)?.typeface = typeface
|
||||||
|
|||||||
Reference in New Issue
Block a user