This library is a glue between the lifecycle of androidx.lifecycle:lifecycle-extensions
and Flow
class of
org.jetbrains.kotlinx:kotlinx-coroutines-core
library. The assumption is that we want the emitted values between
start
and stop
of LifecycleOwner
, so on other moments this library would unsubscribe from the upstream of Flow
.
Also, we support a more general assumption that we want the emitted values after start
and before stop
or
saveState
of SavedStateRegistryOwner
, depends which one gets called sooner.
Also you can find its twin library for RxJava in https://github.com/hadilq/RxLifecycleHandler/.
This source has a sample app, which doesn't do anything, where you can find the usage in MainActivity
,
MainViewModelActivity
and ScopeMainActivity
. However, in MVVM
or MVI
architectural patterns, you can use it
based on the data you want to save in onSaveInstanceState
or not. For now let's restrict ourselves to MVVM
.
If the data you want to propagate is an action, then you probably don't want to save it so in ViewModel
you have.
class MainViewModel : ViewModel() {
private val publisher = BroadcastChannel<String>(CONFLATED)
val stringEmitter = publisher.toLifecycleAware()
}
And in the Activity
or Fragment
you have.
class MyViewModelActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
(viewModel.stringEmitter.observe()) { testString ->
/* use it here */
}
}
}
But if you want to save the propagated data in onSaveInstanceState
method, then you may want to
use it as follows.
class MainViewModel : ViewModel() {
private val extendedPublisher = BroadcastChannel<String>(CONFLATED)
val extendedStringEmitter = extendedPublisher.toELifeAware(KEY)
companion object {
private const val KEY = "key_to_save_string_emitter"
}
}
And in the Activity
or Fragment
you have.
class MyViewModelActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
(viewModel.extendedStringEmitter.observe()) { testString ->
/* use it here */
}
}
}
Here, you may noticed the extra parentheses above, or you may noticed that we didn't passe the
Activity
or Fragment
to the observe
method. In both cases, read the last sentence again!
Because they're related to each other, which means in this library we preferred to avoid writing
this
to pass the Activity
or Fragment
directly in trade off of having odd position of parentheses.
Any way, in case you want to use this library out of MVVM
architectural pattern, you can use it
as follows.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val flow: Flow<String> = ...
// Flow usage
flow
.onEach { }
.catch { }
.onCompletion { }
.observeIn()()
// OR
flow
.onEach { }
.catch { }
.onCompletion { }
.observeIn(life, KEY)()
}
companion object {
private const val KEY = "key_to_save_the_data"
}
}
Enjoy!
Since version 0.4.0 this library is a Kotlin Multiplatform library, so depend on what kind of module you use it in, you can use different artifact IDs. Download via gradle
implementation "com.github.hadilq:coroutines-lifecycle-handler-android:$libVersion"
where the libVersion
is .
Use the above one if you already using this library or you need it in an android module. Use
implementation "com.github.hadilq:coroutines-lifecycle-handler-jvm:$libVersion"
if you need only the interfaces in a Java module. And finally, in a common module of multiplatform project you would use those interfaces as
implementation "com.github.hadilq:coroutines-lifecycle-handler-metadata:$libVersion"
Just create your branch from the master branch, change it, write additional tests, satisfy all tests, create your pull request, thank you, you're awesome.