Search code examples
androidkotlinsingletonsharedpreferencesdatastore

How to share values between different classes in Android?


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?


Solution

  • 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"
                    )
                }
    
            }
        }
    }