英文:
How to share values between different classes in Android?
问题
目前,我正在开发一个应用程序,在这个应用程序中,我需要保存不同类型的数据值,并在需要时从多个类中访问这些数据。目前,我正在使用对象(单例)类来实现这一点,就像下面这样:
object VLineDataHolder {
private val _logsProgress = MutableStateFlow(0)
val logsProgress: StateFlow<Int>
get() = _logsProgress
fun setLogsProgress(logsProgress: Int) {
_logsProgress.value = logsProgress
}
}
我不确定我是否正在以正确的方式处理这个问题,实际上我不需要在用户退出应用程序后保留数据,这就是为什么我没有在这里使用 DataStore 或 SharedPreferences。是否有人可以解释这是否是一个好的解决方案?
英文:
Currently I am developing an app where I have to save values of different types of data and access the data from multiple classes when needed. Currently I am using Object(singleton) classes for that. like below:
object VLineDataHolder {
private val _logsProgress = MutableStateFlow(0)
val logsProgress: StateFlow<Int>
get() = _logsProgress
fun setLogsProgress(logsProgress: Int) {
_logsProgress.value = logsProgress
}
}
I am just not sure If I am doing it in a right way, I don't actually need to persist the data after user exits the app that's why I am not using any DataStore or SharedPreferences here. Can any one explain if it is the good solution or not?
答案1
得分: 1
你可以在单例类内部使用可变的共享流(MutableSharedFlow),创建一种类似总线(Bus)的模式。只需将数据推送到流中,然后从任何位置观察它。例如,当用户登录事件发生时,我想被通知。
object EventBusKotlin {
private val _events = MutableSharedFlow<AuthEvents>()
val events = _events.asSharedFlow()
suspend fun publish(event: AuthEvents) {
_events.emit(event)
}
@OptIn(DelicateCoroutinesApi::class)
suspend inline fun <reified T> subscribe(crossinline onEvent: (T) -> Unit) {
events.filterIsInstance<T>()
.collectLatest { event ->
coroutineContext.ensureActive()
onEvent(event)
}
}
}
sealed class AuthEvents
data class LoginEvent(
val userId: String,
val userName: String
): AuthEvents()
// 观察/订阅事件
@Inject
lateinit var eventBus: EventBusKotlin
// 推送/发布事件
suspend fun postLoginEvent(loginEvent: LoginEvent) {
eventBus.publish(loginEvent)
}
// 订阅和监听最新事件
fun subscribeLoginEvent(lifecycleOwner: LifecycleOwner) {
lifecycleOwner.lifecycleScope.launch {
eventBus.subscribe<AuthEvents> { event ->
when (event) {
is LoginEvent -> Log.d(
"LoginEventHandler",
"${event.userName} 登录成功"
)
}
}
}
}
英文:
You can use mutuable shared flow inside singleton class and creating a Bus type pattern. Just push the data and observe it from anywhere. As example I want to be noticed whenever use login event happens
object EventBusKotlin {
private val _events = MutableSharedFlow<AuthEvents>()
val events = _events.asSharedFlow()
suspend fun publish(event: AuthEvents) {
_events.emit(event)
}
@OptIn(DelicateCoroutinesApi::class)
suspend inline fun <reified T> subscribe(crossinline onEvent: (T) -> Unit) {
events.filterIsInstance<T>()
.collectLatest { event ->
coroutineContext.ensureActive()
onEvent(event)
}
}
}
sealed class AuthEvents
Event model
data class LoginEvent(
val userId: String,
val userName: String
):AuthEvents()
Observing/Subscribing
@Inject
lateinit var eventBus: EventBusKotlin
//push/publish event
suspend fun postLoginEvent(loginEvent: LoginEvent) {
eventBus.publish(loginEvent)
}
// subscribing and listening latest event
fun subscribeLoginEvent(lifecycleOwner: LifecycleOwner) {
lifecycleOwner.lifecycleScope.launch {
eventBus.subscribe<AuthEvents> { event ->
when (event) {
is LoginEvent -> Log.d(
"LoginEventHandler",
"${event.userName} logged-in successfully"
)
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论