ursus
01/02/2022, 4:04 PMprivate fun SharedPreferences.onSharedPreferenceChangedFlow(): Flow<String> {
return callbackFlow {
val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
trySend(key)
}
registerOnSharedPreferenceChangeListener(listener)
awaitClose { unregisterOnSharedPreferenceChangeListener(listener) }
}
}
seems to work, however I do know there is one nasty behavior of the SharedPreferences.registerOnSharedPreferenceChangeListener
, that it only keeps weak references, so the listener might get gc-ed
so I need to hard reference the listener
How would I turn it into a field? Or rather, I think I need a proper CallbackFlow subclass, not just use the builder, right?
And looking at sources, everything is private / internal apitseisel
01/02/2022, 4:21 PMregisterOnSharedPreferenceChangeListener
only keeps weak references.
You listener reference is captured by the lambda you passed to awaitClose
, hence there is an implicit strong reference keeping it alive as long as the `callbackFlow`'s channel is open.Adam Powell
01/02/2022, 4:24 PMursus
01/02/2022, 4:28 PMcreate
builder -- and in that builder there is equivalent setCancellable
which by your sound logic was doing the same..ursus
01/02/2022, 4:30 PMsend
variants should I be using heretseisel
01/02/2022, 5:06 PMtrySend
and trySendBlocking
since you are in a non-suspending context.
I suggest using trySend
most of the time, unless you absolutely don't want to miss any value (that may happen if you use buffer
with a small capacity)ursus
01/02/2022, 5:09 PM