manager: Refactoring data refresh management

New AppData object to optimize data fetching and state management.
This commit is contained in:
ShirkNeko
2025-06-02 17:49:34 +08:00
parent c0e839dd8e
commit b772c8ece1
2 changed files with 120 additions and 29 deletions

View File

@@ -32,11 +32,13 @@ import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
import io.sukisu.ultra.UltraToolInstall
import com.sukisu.ultra.Natives
import com.sukisu.ultra.ksuApp
import com.sukisu.ultra.ui.data.AppData
import com.sukisu.ultra.ui.screen.BottomBarDestination
import com.sukisu.ultra.ui.theme.*
import com.sukisu.ultra.ui.theme.CardConfig.cardAlpha
import com.sukisu.ultra.ui.util.*
import androidx.core.content.edit
import com.sukisu.ultra.ui.data.AppData.DataRefreshManager
import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
import com.sukisu.ultra.ui.webui.initPlatform
import java.util.Locale
@@ -45,33 +47,14 @@ import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.lifecycle.lifecycleScope
import com.sukisu.ultra.ui.data.AppData.getKpmVersionUse
import com.sukisu.ultra.ui.viewmodel.HomeViewModel
import com.sukisu.ultra.ui.viewmodel.SuperUserViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.Dispatchers
// 数据刷新管理
object DataRefreshManager {
private val _superuserCount = MutableStateFlow(0)
private val _moduleCount = MutableStateFlow(0)
private val _kpmModuleCount = MutableStateFlow(0)
val superuserCount: StateFlow<Int> = _superuserCount.asStateFlow()
val moduleCount: StateFlow<Int> = _moduleCount.asStateFlow()
val kpmModuleCount: StateFlow<Int> = _kpmModuleCount.asStateFlow()
fun refreshData() {
_superuserCount.value = getSuperuserCount()
_moduleCount.value = getModuleCount()
_kpmModuleCount.value = getKpmModuleCount()
}
}
class MainActivity : ComponentActivity() {
private lateinit var superUserViewModel: SuperUserViewModel
private lateinit var homeViewModel: HomeViewModel
@@ -197,7 +180,7 @@ class MainActivity : ComponentActivity() {
contentResolver.unregisterContentObserver(contentObserver)
}
val isManager = Natives.becomeManager(ksuApp.packageName)
val isManager = AppData.isManager(ksuApp.packageName)
if (isManager) {
install()
UltraToolInstall.tryToInstall()
@@ -218,7 +201,7 @@ class MainActivity : ComponentActivity() {
LaunchedEffect(Unit) {
initPlatform()
}
CompositionLocalProvider(
LocalSnackbarHost provides snackBarHostState
) {
@@ -327,9 +310,8 @@ class MainActivity : ComponentActivity() {
@Composable
private fun BottomBar(navController: NavHostController) {
val navigator = navController.rememberDestinationsNavigator()
val isManager = Natives.becomeManager(ksuApp.packageName)
val fullFeatured = isManager && !Natives.requireNewKernel() && rootAvailable()
val kpmVersion = getKpmVersion()
val isFullFeatured = AppData.isFullFeatured(ksuApp.packageName)
val kpmVersion = getKpmVersionUse()
val cardColor = MaterialTheme.colorScheme.surfaceContainer
val context = LocalContext.current
@@ -355,7 +337,7 @@ private fun BottomBar(navController: NavHostController) {
BottomBarDestination.entries.forEach { destination ->
if (destination == BottomBarDestination.Kpm) {
if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error") && showKpmInfo && Natives.version >= Natives.MINIMAL_SUPPORTED_KPM) {
if (!fullFeatured && destination.rootRequired) return@forEach
if (!isFullFeatured && destination.rootRequired) return@forEach
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
NavigationBarItem(
selected = isCurrentDestOnBackStack,
@@ -398,7 +380,7 @@ private fun BottomBar(navController: NavHostController) {
)
}
} else if (destination == BottomBarDestination.SuperUser) {
if (!fullFeatured && destination.rootRequired) return@forEach
if (!isFullFeatured && destination.rootRequired) return@forEach
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
NavigationBarItem(
@@ -441,7 +423,7 @@ private fun BottomBar(navController: NavHostController) {
alwaysShowLabel = false
)
} else if (destination == BottomBarDestination.Module) {
if (!fullFeatured && destination.rootRequired) return@forEach
if (!isFullFeatured && destination.rootRequired) return@forEach
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
NavigationBarItem(
@@ -483,7 +465,7 @@ private fun BottomBar(navController: NavHostController) {
alwaysShowLabel = false
)
} else {
if (!fullFeatured && destination.rootRequired) return@forEach
if (!isFullFeatured && destination.rootRequired) return@forEach
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
NavigationBarItem(

View File

@@ -0,0 +1,109 @@
package com.sukisu.ultra.ui.data
import com.sukisu.ultra.Natives
import com.sukisu.ultra.ui.util.getKpmModuleCount
import com.sukisu.ultra.ui.util.getKpmVersion
import com.sukisu.ultra.ui.util.rootAvailable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.withContext
import com.sukisu.ultra.ui.util.getModuleCount
import com.sukisu.ultra.ui.util.getSuperuserCount
object AppData {
object DataRefreshManager {
// 私有状态流
private val _superuserCount = MutableStateFlow(0)
private val _moduleCount = MutableStateFlow(0)
private val _kpmModuleCount = MutableStateFlow(0)
// 公开的只读状态流
val superuserCount: StateFlow<Int> = _superuserCount.asStateFlow()
val moduleCount: StateFlow<Int> = _moduleCount.asStateFlow()
val kpmModuleCount: StateFlow<Int> = _kpmModuleCount.asStateFlow()
/**
* 刷新所有数据计数
*/
fun refreshData() {
_superuserCount.value = getSuperuserCountUse()
_moduleCount.value = getModuleCountUse()
_kpmModuleCount.value = getKpmModuleCountUse()
}
/**
* 异步刷新所有数据
*/
suspend fun refreshDataAsync() = withContext(Dispatchers.IO) {
refreshData()
}
}
/**
* 获取超级用户应用计数
*/
fun getSuperuserCountUse(): Int {
return try {
if (!rootAvailable()) return 0
getSuperuserCount()
} catch (_: Exception) {
0
}
}
/**
* 获取模块计数
*/
fun getModuleCountUse(): Int {
return try {
if (!rootAvailable()) return 0
getModuleCount()
} catch (_: Exception) {
0
}
}
/**
* 获取KPM模块计数
*/
fun getKpmModuleCountUse(): Int {
return try {
if (!rootAvailable()) return 0
val kpmVersion = getKpmVersionUse()
if (kpmVersion.isEmpty() || kpmVersion.startsWith("Error")) return 0
getKpmModuleCount()
} catch (_: Exception) {
0
}
}
/**
* 获取KPM版本
*/
fun getKpmVersionUse(): String {
return try {
if (!rootAvailable()) return ""
val version = getKpmVersion()
if (version.isEmpty()) "" else version
} catch (e: Exception) {
"Error: ${e.message}"
}
}
/**
* 检查是否具有管理员权限
*/
fun isManager(packageName: String): Boolean {
return Natives.becomeManager(packageName)
}
/**
* 检查是否是完整功能模式
*/
fun isFullFeatured(packageName: String): Boolean {
val isManager = Natives.becomeManager(packageName)
return isManager && !Natives.requireNewKernel() && rootAvailable()
}
}