Issue
I have created a location repository that is responsible for collecting location data and transmitting it to whoever listens, the code right now looks something like this:
@Singleton
class LocationRepository @Inject constructor(
app: Application
) {
private val _location = MutableStateFlow<Location?>(null)
private val subscribers = AtomicInteger()
val location: Flow<Location?> = _location.onSubscription {
if (subscribers.getAndIncrement() == 0)
startUpdates()
}.onCompletion {
if (subscribers.decrementAndGet() == 0)
stopUpdates()
}
private val client = LocationServices.getFusedLocationProviderClient(app)
private val locCb = object : LocationCallback() {
override fun onLocationResult(var1: LocationResult?) {
newLocationResult(var1)
}
override fun onLocationAvailability(var1: LocationAvailability) {}
}
private val request = LocationRequest.create()
init {
request.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
request.interval = 5000L
request.fastestInterval = 2500L
}
private fun startUpdates() { //code to start getting location updates }
private fun stopUpdates() { //code to stop getting location updates }
}
right now I am handling the current number of subscribers with an AtomicInteger
, is there a way to run the startUpdates
code and the stopUpdates
code automatically when the first subscriber subscribes and the last subscriber unsubscribes?
Solution
Please check subscriptionCount
property of MutableSharedFlow
, it may be what you are looking for. It has type of StateFlow<Int>
and emits the number of subscribers (active collectors) to this shared flow. Example:
_location.subscriptionCount
.map { count -> count > 0 } // map count into active/inactive flag
.distinctUntilChanged() // only react to true<->false changes
.onEach { isActive -> // configure an action
if (isActive) startUpdates() else stopUpdates()
}
.launchIn(scope) // launch it
Answered By - Sergey
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.