manager: Refactoring data refresh management
New AppData object to optimize data fetching and state management.
This commit is contained in:
@@ -32,11 +32,13 @@ import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
|
|||||||
import io.sukisu.ultra.UltraToolInstall
|
import io.sukisu.ultra.UltraToolInstall
|
||||||
import com.sukisu.ultra.Natives
|
import com.sukisu.ultra.Natives
|
||||||
import com.sukisu.ultra.ksuApp
|
import com.sukisu.ultra.ksuApp
|
||||||
|
import com.sukisu.ultra.ui.data.AppData
|
||||||
import com.sukisu.ultra.ui.screen.BottomBarDestination
|
import com.sukisu.ultra.ui.screen.BottomBarDestination
|
||||||
import com.sukisu.ultra.ui.theme.*
|
import com.sukisu.ultra.ui.theme.*
|
||||||
import com.sukisu.ultra.ui.theme.CardConfig.cardAlpha
|
import com.sukisu.ultra.ui.theme.CardConfig.cardAlpha
|
||||||
import com.sukisu.ultra.ui.util.*
|
import com.sukisu.ultra.ui.util.*
|
||||||
import androidx.core.content.edit
|
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.theme.CardConfig.cardElevation
|
||||||
import com.sukisu.ultra.ui.webui.initPlatform
|
import com.sukisu.ultra.ui.webui.initPlatform
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -45,33 +47,14 @@ import androidx.compose.animation.slideInVertically
|
|||||||
import androidx.compose.animation.slideOutVertically
|
import androidx.compose.animation.slideOutVertically
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.lifecycle.lifecycleScope
|
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.HomeViewModel
|
||||||
import com.sukisu.ultra.ui.viewmodel.SuperUserViewModel
|
import com.sukisu.ultra.ui.viewmodel.SuperUserViewModel
|
||||||
import kotlinx.coroutines.delay
|
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.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.Dispatchers
|
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() {
|
class MainActivity : ComponentActivity() {
|
||||||
private lateinit var superUserViewModel: SuperUserViewModel
|
private lateinit var superUserViewModel: SuperUserViewModel
|
||||||
private lateinit var homeViewModel: HomeViewModel
|
private lateinit var homeViewModel: HomeViewModel
|
||||||
@@ -197,7 +180,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
contentResolver.unregisterContentObserver(contentObserver)
|
contentResolver.unregisterContentObserver(contentObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
val isManager = AppData.isManager(ksuApp.packageName)
|
||||||
if (isManager) {
|
if (isManager) {
|
||||||
install()
|
install()
|
||||||
UltraToolInstall.tryToInstall()
|
UltraToolInstall.tryToInstall()
|
||||||
@@ -218,7 +201,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
initPlatform()
|
initPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalSnackbarHost provides snackBarHostState
|
LocalSnackbarHost provides snackBarHostState
|
||||||
) {
|
) {
|
||||||
@@ -327,9 +310,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun BottomBar(navController: NavHostController) {
|
private fun BottomBar(navController: NavHostController) {
|
||||||
val navigator = navController.rememberDestinationsNavigator()
|
val navigator = navController.rememberDestinationsNavigator()
|
||||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
val isFullFeatured = AppData.isFullFeatured(ksuApp.packageName)
|
||||||
val fullFeatured = isManager && !Natives.requireNewKernel() && rootAvailable()
|
val kpmVersion = getKpmVersionUse()
|
||||||
val kpmVersion = getKpmVersion()
|
|
||||||
val cardColor = MaterialTheme.colorScheme.surfaceContainer
|
val cardColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
@@ -355,7 +337,7 @@ private fun BottomBar(navController: NavHostController) {
|
|||||||
BottomBarDestination.entries.forEach { destination ->
|
BottomBarDestination.entries.forEach { destination ->
|
||||||
if (destination == BottomBarDestination.Kpm) {
|
if (destination == BottomBarDestination.Kpm) {
|
||||||
if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error") && showKpmInfo && Natives.version >= Natives.MINIMAL_SUPPORTED_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)
|
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
selected = isCurrentDestOnBackStack,
|
selected = isCurrentDestOnBackStack,
|
||||||
@@ -398,7 +380,7 @@ private fun BottomBar(navController: NavHostController) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (destination == BottomBarDestination.SuperUser) {
|
} else if (destination == BottomBarDestination.SuperUser) {
|
||||||
if (!fullFeatured && destination.rootRequired) return@forEach
|
if (!isFullFeatured && destination.rootRequired) return@forEach
|
||||||
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
|
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
|
||||||
|
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
@@ -441,7 +423,7 @@ private fun BottomBar(navController: NavHostController) {
|
|||||||
alwaysShowLabel = false
|
alwaysShowLabel = false
|
||||||
)
|
)
|
||||||
} else if (destination == BottomBarDestination.Module) {
|
} else if (destination == BottomBarDestination.Module) {
|
||||||
if (!fullFeatured && destination.rootRequired) return@forEach
|
if (!isFullFeatured && destination.rootRequired) return@forEach
|
||||||
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
|
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
|
||||||
|
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
@@ -483,7 +465,7 @@ private fun BottomBar(navController: NavHostController) {
|
|||||||
alwaysShowLabel = false
|
alwaysShowLabel = false
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
if (!fullFeatured && destination.rootRequired) return@forEach
|
if (!isFullFeatured && destination.rootRequired) return@forEach
|
||||||
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
|
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
|
||||||
|
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
|
|||||||
109
manager/app/src/main/java/com/sukisu/ultra/ui/data/AppData.kt
Normal file
109
manager/app/src/main/java/com/sukisu/ultra/ui/data/AppData.kt
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user