manager: Add initialization to optimize loading of SuperUser and Home data

This commit is contained in:
ShirkNeko
2025-05-31 19:17:43 +08:00
parent 13b1aad4b8
commit 8bf9cd0bee
5 changed files with 73 additions and 17 deletions

View File

@@ -44,8 +44,15 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically 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 com.sukisu.ultra.ui.viewmodel.HomeViewModel
import com.sukisu.ultra.ui.viewmodel.SuperUserViewModel
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
private lateinit var superUserViewModel: SuperUserViewModel
private lateinit var homeViewModel: HomeViewModel
private inner class ThemeChangeContentObserver( private inner class ThemeChangeContentObserver(
handler: Handler, handler: Handler,
private val onThemeChanged: () -> Unit private val onThemeChanged: () -> Unit
@@ -111,6 +118,21 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// 初始化 SuperUserViewModel
superUserViewModel = SuperUserViewModel()
lifecycleScope.launch {
superUserViewModel.fetchAppList()
}
// 初始化 HomeViewModel
homeViewModel = HomeViewModel()
// 预加载数据
lifecycleScope.launch {
homeViewModel.initializeData()
}
val prefs = getSharedPreferences("settings", MODE_PRIVATE) val prefs = getSharedPreferences("settings", MODE_PRIVATE)
val isFirstRun = prefs.getBoolean("is_first_run", true) val isFirstRun = prefs.getBoolean("is_first_run", true)
@@ -237,6 +259,14 @@ class MainActivity : ComponentActivity() {
if (!ThemeConfig.backgroundImageLoaded && !ThemeConfig.preventBackgroundRefresh) { if (!ThemeConfig.backgroundImageLoaded && !ThemeConfig.preventBackgroundRefresh) {
loadCustomBackground() loadCustomBackground()
} }
lifecycleScope.launch {
superUserViewModel.fetchAppList()
}
lifecycleScope.launch {
homeViewModel.initializeData()
}
} }
private val destroyListeners = mutableListOf<() -> Unit>() private val destroyListeners = mutableListOf<() -> Unit>()

View File

@@ -42,7 +42,7 @@ import androidx.compose.material.icons.filled.Security
import androidx.compose.material.icons.filled.SettingsSuggest import androidx.compose.material.icons.filled.SettingsSuggest
import androidx.compose.material.icons.filled.Storage import androidx.compose.material.icons.filled.Storage
import androidx.compose.material.icons.outlined.Block import androidx.compose.material.icons.outlined.Block
import androidx.compose.material.icons.outlined.CheckCircle import androidx.compose.material.icons.outlined.TaskAlt
import androidx.compose.material.icons.outlined.Warning import androidx.compose.material.icons.outlined.Warning
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenu
@@ -121,11 +121,8 @@ fun HomeScreen(navigator: DestinationsNavigator) {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
// 初始化加载用户设置
viewModel.loadUserSettings(context) viewModel.loadUserSettings(context)
// 初始化数据
viewModel.initializeData() viewModel.initializeData()
// 检查更新
viewModel.checkForUpdates(context) viewModel.checkForUpdates(context)
} }
@@ -370,7 +367,7 @@ private fun StatusCard(
} }
Icon( Icon(
Icons.Outlined.CheckCircle, Icons.Outlined.TaskAlt,
contentDescription = stringResource(R.string.home_working), contentDescription = stringResource(R.string.home_working),
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(24.dp) modifier = Modifier.size(24.dp)

View File

@@ -72,7 +72,7 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
LaunchedEffect(key1 = navigator) { LaunchedEffect(key1 = navigator) {
viewModel.search = "" viewModel.search = ""
if (viewModel.appList.isEmpty()) { if (viewModel.appList.isEmpty()) {
viewModel.fetchAppList() // viewModel.fetchAppList()
} }
} }

View File

@@ -33,13 +33,12 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import com.topjohnwu.superuser.internal.Utils.context import com.topjohnwu.superuser.internal.Utils.context
/**
* @author ShirkNeko
* @date 2025/5/31.
*/
class HomeViewModel : ViewModel() { class HomeViewModel : ViewModel() {
companion object { companion object {
private const val TAG = "HomeViewModel" private const val TAG = "HomeViewModel"
private val systemStatusCache = mutableMapOf<String, SystemStatus>()
private val systemInfoCache = mutableMapOf<String, SystemInfo>()
private val versionInfoCache = mutableMapOf<String, LatestVersionInfo>()
} }
// 系统状态 // 系统状态
@@ -117,10 +116,22 @@ class HomeViewModel : ViewModel() {
// 初始化数据 // 初始化数据
fun initializeData() { fun initializeData() {
viewModelScope.launch { viewModelScope.launch {
val cachedStatus = systemStatusCache["status"]
val cachedInfo = systemInfoCache["info"]
if (cachedStatus != null) {
systemStatus = cachedStatus
} else {
fetchSystemStatus() fetchSystemStatus()
}
if (cachedInfo != null) {
systemInfo = cachedInfo
} else {
fetchSystemInfo() fetchSystemInfo()
} }
} }
}
// 检查更新 // 检查更新
fun checkForUpdates(context: Context) { fun checkForUpdates(context: Context) {
@@ -130,8 +141,17 @@ class HomeViewModel : ViewModel() {
.getBoolean("check_update", true) .getBoolean("check_update", true)
if (checkUpdate) { if (checkUpdate) {
val cachedVersion = versionInfoCache["version"]
if (cachedVersion != null) {
latestVersionInfo = cachedVersion
return@launch
}
val start = SystemClock.elapsedRealtime() val start = SystemClock.elapsedRealtime()
latestVersionInfo = checkNewVersion() val newVersionInfo = checkNewVersion()
latestVersionInfo = newVersionInfo
versionInfoCache["version"] = newVersionInfo
Log.i(TAG, "Update check completed in ${SystemClock.elapsedRealtime() - start}ms") Log.i(TAG, "Update check completed in ${SystemClock.elapsedRealtime() - start}ms")
} }
} catch (e: Exception) { } catch (e: Exception) {
@@ -145,6 +165,9 @@ class HomeViewModel : ViewModel() {
isRefreshing = true isRefreshing = true
viewModelScope.launch { viewModelScope.launch {
try { try {
systemStatusCache.clear()
systemInfoCache.clear()
versionInfoCache.clear()
fetchSystemStatus() fetchSystemStatus()
fetchSystemInfo() fetchSystemInfo()
checkForUpdates(context) checkForUpdates(context)
@@ -165,7 +188,7 @@ class HomeViewModel : ViewModel() {
if (it >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && kernelVersion.isGKI()) Natives.isLkmMode else null if (it >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && kernelVersion.isGKI()) Natives.isLkmMode else null
} }
systemStatus = SystemStatus( val newStatus = SystemStatus(
isManager = isManager, isManager = isManager,
ksuVersion = ksuVersion, ksuVersion = ksuVersion,
lkmMode = lkmMode, lkmMode = lkmMode,
@@ -174,6 +197,9 @@ class HomeViewModel : ViewModel() {
isKpmConfigured = Natives.isKPMEnabled(), isKpmConfigured = Natives.isKPMEnabled(),
requireNewKernel = isManager && Natives.requireNewKernel() requireNewKernel = isManager && Natives.requireNewKernel()
) )
systemStatus = newStatus
systemStatusCache["status"] = newStatus
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Error fetching system status", e) Log.e(TAG, "Error fetching system status", e)
} }
@@ -209,7 +235,7 @@ class HomeViewModel : ViewModel() {
} }
} }
systemInfo = SystemInfo( val newInfo = SystemInfo(
kernelRelease = uname.release, kernelRelease = uname.release,
androidVersion = Build.VERSION.RELEASE, androidVersion = Build.VERSION.RELEASE,
deviceModel = getDeviceModel(), deviceModel = getDeviceModel(),
@@ -225,6 +251,9 @@ class HomeViewModel : ViewModel() {
moduleCount = getModuleCount(), moduleCount = getModuleCount(),
kpmModuleCount = getKpmModuleCount() kpmModuleCount = getKpmModuleCount()
) )
systemInfo = newInfo
systemInfoCache["info"] = newInfo
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Error fetching system info", e) Log.e(TAG, "Error fetching system info", e)
} }

View File

@@ -34,7 +34,7 @@ class SuperUserViewModel : ViewModel() {
val isPlatformAlive get() = Platform.isAlive val isPlatformAlive get() = Platform.isAlive
companion object { companion object {
private const val TAG = "SuperUserViewModel" private const val TAG = "SuperUserViewModel"
private var apps by mutableStateOf<List<AppInfo>>(emptyList()) var apps by mutableStateOf<List<AppInfo>>(emptyList())
} }
@Parcelize @Parcelize
@@ -171,7 +171,7 @@ class SuperUserViewModel : ViewModel() {
fetchAppList() // 刷新列表以显示最新状态 fetchAppList() // 刷新列表以显示最新状态
} }
// 更新本地应用配置,避免重新获取整个列表导致滚动位置重置 // 更新本地应用配置
fun updateAppProfileLocally(packageName: String, updatedProfile: Natives.Profile) { fun updateAppProfileLocally(packageName: String, updatedProfile: Natives.Profile) {
apps = apps.map { app -> apps = apps.map { app ->
if (app.packageName == packageName) { if (app.packageName == packageName) {