From b772c8ece1dbd98371482cc524036a20e9aa367d Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Mon, 2 Jun 2025 17:49:34 +0800 Subject: [PATCH] manager: Refactoring data refresh management New AppData object to optimize data fetching and state management. --- .../java/com/sukisu/ultra/ui/MainActivity.kt | 40 ++----- .../java/com/sukisu/ultra/ui/data/AppData.kt | 109 ++++++++++++++++++ 2 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 manager/app/src/main/java/com/sukisu/ultra/ui/data/AppData.kt diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt index f8afa160..5fd7664b 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt @@ -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 = _superuserCount.asStateFlow() - val moduleCount: StateFlow = _moduleCount.asStateFlow() - val kpmModuleCount: StateFlow = _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( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/data/AppData.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/data/AppData.kt new file mode 100644 index 00000000..eff53f10 --- /dev/null +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/data/AppData.kt @@ -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 = _superuserCount.asStateFlow() + val moduleCount: StateFlow = _moduleCount.asStateFlow() + val kpmModuleCount: StateFlow = _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() + } +} \ No newline at end of file