fix(scale): 修复主从设备IP显示异常及RecyclerView滑动崩溃

- 新增 NetworkUtil 统一获取本机IP,兼容 Android 12+(ConnectivityManager)和低版本(WifiManager)
- 主设备IP改为实时读取,修复App启动时网络未就绪导致IP缓存为空的问题
- MasterScaleActivity/SlaveActivity 关闭RecyclerView默认ItemAnimator,消除高频刷新时的闪烁
- BaseActivity.hideSystemBars 加防重入标志,避免重复调用setDecorFitsSystemWindows触发布局重绘导致滑动崩溃
- 新增 CrashHandler,崩溃时记录日志并自动重启应用

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-08 18:09:41 +08:00
co-authored by Claude Sonnet 4.6
parent 29228b069b
commit 34adc0fe56
7 changed files with 322 additions and 29 deletions
@@ -14,6 +14,7 @@ import com.shuwei.dish.match.databinding.ActivityMasterScaleBinding
import com.shuwei.dish.match.databinding.ListItemScaleDataBinding
import com.shuwei.dish.match.scale.ScaleData
import com.shuwei.dish.match.scale.ScaleServiceManager
import com.shuwei.dish.match.utils.NetworkUtil
import com.shuwei.dish.match.utils.WeightUtil
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -50,6 +51,7 @@ class MasterScaleActivity : BaseActivity() {
setHeaderBackground()
binding.rvScaleList.layoutManager = LinearLayoutManager(this)
binding.rvScaleList.itemAnimator = null // 关闭默认动画,避免数据频繁更新时出现闪烁错乱
binding.rvScaleList.adapter = adapter
observeScaleData()
@@ -66,6 +68,8 @@ class MasterScaleActivity : BaseActivity() {
flow.collectLatest { scaleMap ->
// 按 deviceId 分组,本机设备排最前,其余按 deviceId 排序
val localId = com.shuwei.dish.match.base.GlobalData.deviceId
// 本机 IP 实时读取,避免 App 启动时网络未就绪导致缓存为空
val localIp = NetworkUtil.getLocalIpAddress(this@MasterScaleActivity)
val groups = scaleMap.values
.groupBy { it.deviceId }
.entries
@@ -73,7 +77,8 @@ class MasterScaleActivity : BaseActivity() {
.map { (deviceId, scales) ->
DeviceGroup(
deviceId = deviceId,
ip = scales.firstOrNull()?.ip ?: "",
ip = if (deviceId == localId) localIp
else scales.firstOrNull { it.ip.isNotEmpty() }?.ip ?: "",
scales = scales.sortedBy { it.address }
)
}
@@ -1,7 +1,6 @@
package com.shuwei.dish.match.ui
import android.annotation.SuppressLint
import android.net.wifi.WifiManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
@@ -12,6 +11,7 @@ import com.shuwei.dish.match.base.GlobalData
import com.shuwei.dish.match.databinding.ActivitySlaveBinding
import com.shuwei.dish.match.databinding.ListItemScaleRowBinding
import com.shuwei.dish.match.scale.ScaleServiceManager
import com.shuwei.dish.match.utils.NetworkUtil
import com.shuwei.dish.match.utils.WeightUtil
/**
@@ -41,6 +41,7 @@ class SlaveActivity : BaseActivity() {
binding.tvDeviceId.text = "设备:${GlobalData.deviceId}"
binding.tvDeviceIp.text = "IP${getLocalIpAddress()}"
binding.rvScaleList.layoutManager = LinearLayoutManager(this)
binding.rvScaleList.itemAnimator = null // 关闭默认动画,避免数据频繁更新时出现闪烁错乱
binding.rvScaleList.adapter = adapter
updateMasterStatus(false)
@@ -101,19 +102,11 @@ class SlaveActivity : BaseActivity() {
}
/**
* 获取本机 WiFi IP 地址
* 优先使用 WifiManager获取失败时返回"未知"
* 获取本机局域网 IP,委托给 NetworkUtil 统一处理版本兼容
* 获取失败时返回"未知"
*/
@SuppressLint("WifiManagerLeak")
private fun getLocalIpAddress(): String {
return try {
val wifiManager = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
val ip = wifiManager.connectionInfo.ipAddress
if (ip == 0) "未知" else
"${ip and 0xFF}.${ip shr 8 and 0xFF}.${ip shr 16 and 0xFF}.${ip shr 24 and 0xFF}"
} catch (e: Exception) {
"未知"
}
return NetworkUtil.getLocalIpAddress(this).ifEmpty { "未知" }
}
private class ScaleAdapter(private val data: List<ScaleItem>) :