1、减少io操作使用冷流方式一次性完成通知消息的处理
This commit is contained in:
shenzuqiang 2026-03-12 10:17:23 +08:00
parent db36d63082
commit 8c21b3127e
8 changed files with 68 additions and 124 deletions

View File

@ -111,34 +111,33 @@ class MainActivity : ComponentActivity(), LoadingCallback {
generalViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application))[GeneralViewModel::class.java] generalViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application))[GeneralViewModel::class.java]
val globalStateManager = remember { GlobalStateManager(context) } val globalStateManager = remember { GlobalStateManager(context) }
val updateAppNotify by globalStateManager.globalUpdateNotifyFlow().collectAsState(initial = false)
val updateUserConfigNotify by globalStateManager.globalUserConfigNotifyFlow().collectAsState(initial = false)
val updateUniUpdateNotify by globalStateManager.globalUniUpdateNotifyFlow().collectAsState(initial = false) val updateUniUpdateNotify by globalStateManager.globalUniUpdateNotifyFlow().collectAsState(initial = false)
// val updateGlobalLoadingNotify by globalStateManager.isGlobalLoadingFlow().collectAsState(initial = false)
//重置状态信息(防止异常退出导致状态失效) //重置状态信息(防止异常退出导致状态失效)
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
globalStateManager.apply { globalStateManager.apply {
storeGlobalUpdateNotify(false)
storeGlobalUserConfigNotify(false)
storeGlobalUniUpdateNotify(false) storeGlobalUniUpdateNotify(false)
// storeGlobalLoading(false)
} }
} }
val isGlobalLoading by generalViewModel.isLoading.collectAsState() val isGlobalLoading by generalViewModel.isLoading.collectAsState()
// 下载小程序资源(在跳转指定页面时,未下载资源需要提示)
var showUniDownloadDialog by remember { mutableStateOf(false) } var showUniDownloadDialog by remember { mutableStateOf(false) }
var downloadUniEntity by remember { mutableStateOf<UniVersionEntity?>(null) } var downloadUniEntity by remember { mutableStateOf<UniVersionEntity?>(null) }
// 软件更新提示
var showUpdateDialog by remember { mutableStateOf(false) }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
GeneralViewModel.GlobalEventBus.events.collect { event -> GeneralViewModel.GlobalEventBus.events.collect { event ->
when (event) { when (event) {
// 软件更新提示
is GeneralViewModel.GlobalEvent.ShowAppUpdateNotify -> {
showUpdateDialog = true
}
// 小程序资源下载提示
is GeneralViewModel.GlobalEvent.ShowUniDownloadNotify -> { is GeneralViewModel.GlobalEvent.ShowUniDownloadNotify -> {
downloadUniEntity = event.entity downloadUniEntity = event.entity
showUniDownloadDialog = true showUniDownloadDialog = true
} }
is GeneralViewModel.GlobalEvent.ShowAppUpdateNotify -> {
// 处理 App 更新弹窗逻辑
}
// ... 处理其他事件 // ... 处理其他事件
else -> {} else -> {}
} }
@ -190,16 +189,6 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
//还原全局用户配置通知
LaunchedEffect(updateUserConfigNotify) {
delay(300)
if(updateUserConfigNotify == true){
coroutineScope.launch {
globalStateManager.storeGlobalUserConfigNotify(false)
}
}
}
//提示下载小程序资源(在跳转指定页面时,未下载资源需要提示) //提示下载小程序资源(在跳转指定页面时,未下载资源需要提示)
val progressWGTToPageState = remember { mutableFloatStateOf(0f) } val progressWGTToPageState = remember { mutableFloatStateOf(0f) }
LaunchedEffect(showUniDownloadDialog) { LaunchedEffect(showUniDownloadDialog) {
@ -353,21 +342,20 @@ class MainActivity : ComponentActivity(), LoadingCallback {
//App更新提示 //App更新提示
val isStartDownload = mutableStateOf(false) val isStartDownload = mutableStateOf(false)
val progressState = mutableFloatStateOf(0f) val progressState = mutableFloatStateOf(0f)
if(updateAppNotify == true){ if(showUpdateDialog){
val versionEntity = PreferenceUtil.getUserConfig()?.config?.versionEntity
versionEntity?.let{ versionEntity->
UpdateDialog( UpdateDialog(
title = PreferenceUtil.getUserConfig()?.config?.versionEntity?.title?:"新版本,更新提示", title = versionEntity.title,
newVersion = "V${PreferenceUtil.getUserConfig()?.config?.versionEntity?.version}", newVersion = "V${versionEntity.version}",
desc = PreferenceUtil.getUserConfig()?.config?.versionEntity?.description?:"", desc = versionEntity.description,
url = PreferenceUtil.getUserConfig()?.config?.versionEntity?.url?:"", url = versionEntity.url,
scope = coroutineScope, isForce = versionEntity.force,
isForce = PreferenceUtil.getUserConfig()?.config?.versionEntity?.force?:false,
isStartDown = isStartDownload, isStartDown = isStartDownload,
downProgress = progressState downProgress = progressState
){ state, isCancel, url -> ){ state, isCancel, url ->
if(isCancel) { if(isCancel) {
coroutineScope.launch { showUpdateDialog = false
globalStateManager.storeGlobalUpdateNotify(state)
}
} }
if(!isCancel){ if(!isCancel){
isStartDownload.value = true isStartDownload.value = true
@ -384,12 +372,8 @@ class MainActivity : ComponentActivity(), LoadingCallback {
filePath?.let { filePath?.let {
UpdateUtils.install(context,it) UpdateUtils.install(context,it)
} }
if(PreferenceUtil.getUserConfig()?.config?.versionEntity?.force == false) { if(!versionEntity.force) {
coroutineScope.launch { showUpdateDialog = state
globalStateManager.storeGlobalUpdateNotify(
state
)
}
} }
} }
} }
@ -397,10 +381,10 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
} }
}
//全局加载提示 //全局加载提示
if(isGlobalLoading){ if(isGlobalLoading){
// if (updateGlobalLoadingNotify == true) {
Log.i("HomeScreen","isStartOn--->${System.currentTimeMillis()}") Log.i("HomeScreen","isStartOn--->${System.currentTimeMillis()}")
Box( Box(
modifier = Modifier modifier = Modifier
@ -435,7 +419,6 @@ class MainActivity : ComponentActivity(), LoadingCallback {
override fun showLoading() { override fun showLoading() {
lifecycleScope.launch { lifecycleScope.launch {
// GlobalStateManager(this@MainActivity).storeGlobalLoading(true)
generalViewModel.setLoading(true) generalViewModel.setLoading(true)
} }
@ -444,7 +427,6 @@ class MainActivity : ComponentActivity(), LoadingCallback {
override fun hideLoading() { override fun hideLoading() {
lifecycleScope.launch { lifecycleScope.launch {
delay(3000L) delay(3000L)
// GlobalStateManager(this@MainActivity).storeGlobalLoading(false)
generalViewModel.setLoading(false) generalViewModel.setLoading(false)
} }
} }

View File

@ -178,6 +178,7 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
composable(ScreenRoute.Home.route) { composable(ScreenRoute.Home.route) {
HomeScreen( HomeScreen(
navController = navController, navController = navController,
loginViewModel = loginViewModel,
generalViewModel = generalViewModel, generalViewModel = generalViewModel,
loadingCallback = LocalContext.current as? LoadingCallback loadingCallback = LocalContext.current as? LoadingCallback
) )
@ -185,6 +186,7 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
composable(ScreenRoute.Mine.route) { composable(ScreenRoute.Mine.route) {
MineScreen( MineScreen(
navController = navController, navController = navController,
loginViewModel = loginViewModel,
generalViewModel = generalViewModel generalViewModel = generalViewModel
) )
} }

View File

@ -53,7 +53,6 @@ fun UpdateDialog(
newVersion: String = "V1.0.0", newVersion: String = "V1.0.0",
desc: String = "修复了一些问题,新增了一些功能", desc: String = "修复了一些问题,新增了一些功能",
url: String, url: String,
scope: CoroutineScope,
isForce: Boolean = false, isForce: Boolean = false,
isStartDown: MutableState<Boolean>, isStartDown: MutableState<Boolean>,
downProgress: MutableState<Float>, downProgress: MutableState<Float>,

View File

@ -61,6 +61,7 @@ import com.img.rabbit.route.ScreenRoute
import com.img.rabbit.utils.UniAppUtils import com.img.rabbit.utils.UniAppUtils
import com.img.rabbit.utils.UniMpUpdate import com.img.rabbit.utils.UniMpUpdate
import com.img.rabbit.viewmodel.GeneralViewModel import com.img.rabbit.viewmodel.GeneralViewModel
import com.img.rabbit.viewmodel.LoginViewModel
import com.img.rabbit.viewmodel.ReportViewModel import com.img.rabbit.viewmodel.ReportViewModel
import io.dcloud.feature.sdk.DCUniMPSDK import io.dcloud.feature.sdk.DCUniMPSDK
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -71,6 +72,7 @@ import org.json.JSONObject
@Composable @Composable
fun HomeScreen( fun HomeScreen(
navController: NavHostController, navController: NavHostController,
loginViewModel: LoginViewModel,
generalViewModel: GeneralViewModel, generalViewModel: GeneralViewModel,
reportViewModel: ReportViewModel = viewModel(), reportViewModel: ReportViewModel = viewModel(),
loadingCallback: LoadingCallback? loadingCallback: LoadingCallback?
@ -86,8 +88,6 @@ fun HomeScreen(
// 只有当当前路由处于首页 Tab 之一时,才激活 BackHandler // 只有当当前路由处于首页 Tab 之一时,才激活 BackHandler
var lastClickTime by remember { mutableLongStateOf(0L) } var lastClickTime by remember { mutableLongStateOf(0L) }
val updateUserConfigNotify by GlobalStateManager(context).globalUserConfigNotifyFlow().collectAsState(initial = false)
BackHandler(enabled = (currentRoute == ScreenRoute.Home.route)) { BackHandler(enabled = (currentRoute == ScreenRoute.Home.route)) {
val currentTime = System.currentTimeMillis() val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime > 2000) { if (currentTime - lastClickTime > 2000) {
@ -113,8 +113,8 @@ fun HomeScreen(
var homeIconConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.homeIconEntity) } var homeIconConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.homeIconEntity) }
var uniVersionConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.uniVersionEntity) } var uniVersionConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.uniVersionEntity) }
LaunchedEffect(updateUserConfigNotify) { LaunchedEffect(loginViewModel.userConfigResult.value) {
if(updateUserConfigNotify == true){ if(loginViewModel.userConfigResult.value != null){
homeIconConfig = PreferenceUtil.getUserConfig()?.config?.homeIconEntity homeIconConfig = PreferenceUtil.getUserConfig()?.config?.homeIconEntity
uniVersionConfig = PreferenceUtil.getUserConfig()?.config?.uniVersionEntity uniVersionConfig = PreferenceUtil.getUserConfig()?.config?.uniVersionEntity
} }
@ -1490,7 +1490,7 @@ fun HomeScreen(
@Preview(showBackground = true) @Preview(showBackground = true)
@Composable @Composable
private fun PreviewHomeScreen() { private fun PreviewHomeScreen() {
HomeScreen(navController = rememberNavController(), generalViewModel = viewModel(), reportViewModel = viewModel(), object: LoadingCallback{ HomeScreen(navController = rememberNavController(), loginViewModel = viewModel(), generalViewModel = viewModel(), reportViewModel = viewModel(), object: LoadingCallback{
override fun showLoading() { override fun showLoading() {
} }

View File

@ -21,7 +21,7 @@ import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -48,7 +48,6 @@ import coil3.compose.AsyncImage
import com.img.rabbit.BuildConfig import com.img.rabbit.BuildConfig
import com.img.rabbit.R import com.img.rabbit.R
import com.img.rabbit.components.CenterToast import com.img.rabbit.components.CenterToast
import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.route.ScreenRoute import com.img.rabbit.route.ScreenRoute
import com.img.rabbit.utils.AppUpdate import com.img.rabbit.utils.AppUpdate
@ -63,15 +62,14 @@ import kotlinx.coroutines.launch
fun MineScreen( fun MineScreen(
navController: NavHostController, navController: NavHostController,
viewModel: MineViewModel = viewModel(), viewModel: MineViewModel = viewModel(),
loginViewModel: LoginViewModel,
generalViewModel: GeneralViewModel, generalViewModel: GeneralViewModel,
) { ) {
val TAG = "Rabbit_Mine" val TAG = "Rabbit_Mine"
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
var updateUserConfigNotify by mutableStateOf(GlobalStateManager(context).globalUserConfigNotifyFlow().collectAsState(initial = false)) //用户数据
var userInfo by remember { mutableStateOf(PreferenceUtil.getUserInfo()) } var userInfo by remember { mutableStateOf(PreferenceUtil.getUserInfo()) }
// 获取当前路由状态 // 获取当前路由状态
val navBackStackEntry by navController.currentBackStackEntryAsState() val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route val currentRoute = navBackStackEntry?.destination?.route
@ -88,9 +86,9 @@ fun MineScreen(
} }
} }
//刷新用户信息 LaunchedEffect(loginViewModel.userConfigResult.value) {
if(updateUserConfigNotify.value == true){ if(loginViewModel.userConfigResult.value != null){
scope.launch { // 等待200ms确保用户配置已经刷新
delay(200) delay(200)
userInfo = PreferenceUtil.getUserInfo() userInfo = PreferenceUtil.getUserInfo()
@ -451,7 +449,8 @@ fun MineScreen(
//提示执行更新 //提示执行更新
//startUpdate(result, fragment) //startUpdate(result, fragment)
scope.launch { scope.launch {
GlobalStateManager(context).storeGlobalUpdateNotify(true) GeneralViewModel.GlobalEventBus.emit(
GeneralViewModel.GlobalEvent.ShowAppUpdateNotify)
} }
} else { } else {
CenterToast.show(tips) CenterToast.show(tips)
@ -568,5 +567,5 @@ fun MineScreen(
@Preview(showBackground = true) @Preview(showBackground = true)
@Composable @Composable
private fun PreviewMineScreen(){ private fun PreviewMineScreen(){
MineScreen(navController = rememberNavController(), generalViewModel = viewModel()) MineScreen(navController = rememberNavController(), loginViewModel = viewModel(), generalViewModel = viewModel())
} }

View File

@ -15,37 +15,9 @@ class GlobalStateManager(
private val context: Context private val context: Context
) { ) {
companion object { companion object {
private val GLOBAL_LOADING = booleanPreferencesKey("global_loading")
private val GLOBAL_UPDATE_NOTIFY = booleanPreferencesKey("global_update_notify")
private val GLOBAL_UNI_UPDATE_NOTIFY = booleanPreferencesKey("global_uni_update_notify") private val GLOBAL_UNI_UPDATE_NOTIFY = booleanPreferencesKey("global_uni_update_notify")
private val GLOBAL_UNI_DOWNLOAD_NOTIFY = booleanPreferencesKey("global_uni_download_notify")
private val GLOBAL_USER_CONFIG_NOTIFY = booleanPreferencesKey("global_user_config_notify")
} }
// suspend fun storeGlobalLoading(value: Boolean) {
// context.storeData.edit { preferences ->
// preferences[GLOBAL_LOADING] = value
// }
// }
// fun isGlobalLoadingFlow(): Flow<Boolean?> {
// return context.storeData.data.map {
// preferences ->
// preferences[GLOBAL_LOADING]
// }
// }
suspend fun storeGlobalUpdateNotify(value: Boolean) {
context.storeData.edit { preferences ->
preferences[GLOBAL_UPDATE_NOTIFY] = value
}
}
fun globalUpdateNotifyFlow(): Flow<Boolean?> {
return context.storeData.data.map {
preferences ->
preferences[GLOBAL_UPDATE_NOTIFY]
}
}
suspend fun storeGlobalUniUpdateNotify(value: Boolean) { suspend fun storeGlobalUniUpdateNotify(value: Boolean) {
context.storeData.edit { preferences -> context.storeData.edit { preferences ->
@ -59,19 +31,4 @@ class GlobalStateManager(
} }
} }
suspend fun storeGlobalUserConfigNotify(value: Boolean) {
context.storeData.edit { preferences ->
preferences[GLOBAL_USER_CONFIG_NOTIFY] = value
}
}
fun globalUserConfigNotifyFlow(): Flow<Boolean?> {
return context.storeData.data.map {
preferences ->
preferences[GLOBAL_USER_CONFIG_NOTIFY]
}
}
} }

View File

@ -16,6 +16,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.img.rabbit.bean.response.UniVersionEntity import com.img.rabbit.bean.response.UniVersionEntity
import com.img.rabbit.bean.response.VersionEntity
import com.img.rabbit.config.Constants import com.img.rabbit.config.Constants
import com.img.rabbit.provider.api.ApiManager import com.img.rabbit.provider.api.ApiManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
@ -43,9 +44,9 @@ class GeneralViewModel: BaseViewModel(){
// 可以定义一个事件密封类,方便扩展 // 可以定义一个事件密封类,方便扩展
sealed class GlobalEvent { sealed class GlobalEvent {
object ShowAppUpdateNotify : GlobalEvent()
data class ShowUniDownloadNotify(val entity: UniVersionEntity) : GlobalEvent() data class ShowUniDownloadNotify(val entity: UniVersionEntity) : GlobalEvent()
data class ShowUniUpdateNotify(val entity: UniVersionEntity) : GlobalEvent() data class ShowUniUpdateNotify(val entity: UniVersionEntity) : GlobalEvent()
object ShowAppUpdateNotify : GlobalEvent()
} }
object GlobalEventBus { object GlobalEventBus {

View File

@ -108,17 +108,21 @@ class LoginViewModel : BaseViewModel() {
userConfigResult.value = response userConfigResult.value = response
if(isInitConfig){ if(isInitConfig){
AppUpdate.checkUpdate(response.data.config?.versionEntity) { isUpdate, isForce, _ -> val versionEntity = response.data.config?.versionEntity
if(isUpdate && isForce){ AppUpdate.checkUpdate(versionEntity) { isUpdate, _, _ ->
//强制更新 if(isUpdate){
// 有更新,提示更新
viewModelScope.launch{ viewModelScope.launch{
applicationContext?.let { GlobalStateManager(it) }?.storeGlobalUpdateNotify(true) versionEntity?.let {
GeneralViewModel.GlobalEventBus.emit(
GeneralViewModel.GlobalEvent.ShowAppUpdateNotify)
}
} }
} }
} }
} }
//以下是刷新状态 //以下是刷新状态
applicationContext?.let { GlobalStateManager(it) }?.storeGlobalUserConfigNotify(true) // applicationContext?.let { GlobalStateManager(it) }?.storeGlobalUserConfigNotify(true)
}else{ }else{
Log.w("LoginViewModel", "获取配置失败: code=${response.code}, message=${response.message}") Log.w("LoginViewModel", "获取配置失败: code=${response.code}, message=${response.message}")
} }