manager: Add initialization to optimize loading of SuperUser and Home data
This commit is contained in:
@@ -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>()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user