Handle Android Lifecycle methods inside composable function
Android Lifecycle
LifeCycle is a class from androidx.lifecycle package which helps us to get the information and observe on the lifecycle state of components like Activities and fragments
Two things to consider
1.State : Created,Started,Resumed,Destroyed and Initialized
2.Event : ON_CREATE , ON_START, ON_RESUME,ON_PAUSE, ON_STOP and ON_DESTROY
As the legend diagram follows to explain the same
In Activities and fragments , there are methods expose from Activity() and Fragment() class to observe these lifecycle events to meet our requirements in UI. But in compose , there are no such methods to observe the lifecycle states and events which is in built with composable . In the following ways we can get to know the lifecycle state and events.
LifeCycle Library
androidx.lifecycle
- includes APIs to observe and know the lifecycle state.
Get Lifecycle State with Flows
Property from lifecycle which provides Lifecycle.State as a kotlin state flow
collect this flow as state
we can read these states during UI composition
There are 2 ways to do this
1.currentStateFlow
- this is from
lifecycle-common
module
val stateFlow = LocalLifecycleOwner.current.lifecycle.currentStateFlow
val currentLifecycleState by stateFlow.collectAsState()
Log.d("LifecycleScreen", "Lifecycle state: ${currentLifecycleState.name}")
/*
* When launched ->
* LifecycleScreen: RESUMED
* When Back button tapped ->
* Lifecycle state: STARTED
* When Home button tapped ->
* Lifecycle state: STARTED
* Lifecycle state: CREATED
* When recent button tapped ->
* Lifecycle state: STARTED
* Lifecycle state: CREATED
*
*/
2.currentStateAsState
lifecycle-runtime-compose
- provides easy way to read current lifecycle state .
val currentLifecycleState = LocalLifecycleOwner.current.lifecycle
.currentStateAsState()
Log.d("LifecycleScreen", "Lifecycle state: ${currentLifecycleState.value}")
/*
* When launched ->
* LifecycleScreen: RESUMED
* When Back button tapped ->
* Lifecycle state: STARTED
* When Home button tapped ->
* Lifecycle state: STARTED
* Lifecycle state: CREATED
* When recent button tapped ->
* Lifecycle state: STARTED
* Lifecycle state: CREATED
*
*/
LifecycleEventEffect
- allows us to run a block of code when certain
Lifecycle.Event
occurs
@Composable
fun LifecycleScreen() {
val textValue = remember { mutableStateOf("") }
Text(
textValue.value,
fontSize = 32.sp,
modifier = Modifier.padding(32.dp)
)
LifecycleEventEffect(Lifecycle.Event.ON_CREATE) {
Log.d("LifecycleScreen", "LifecycleScreen: The current state is ON_CREATE")
}
LifecycleEventEffect(Lifecycle.Event.ON_START) {
Log.d("LifecycleScreen", "LifecycleScreen: The current state is ON_START")
}
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
Log.d("LifecycleScreen", "LifecycleScreen: The current state is ON_RESUME")
textValue.value = "ON_RESUME"
}
LifecycleEventEffect(Lifecycle.Event.ON_PAUSE) {
Log.d("LifecycleScreen", "LifecycleScreen: The current state is ON_PAUSE")
textValue.value = "ON_PAUSE"
}
LifecycleEventEffect(Lifecycle.Event.ON_STOP) {
Log.d("LifecycleScreen", "LifecycleScreen: The current state is ON_STOP")
}
}
The logs are as follows
1.when the above compose is launched for first time ,
LifecycleScreen D LifecycleScreen: The current state is ON_CREATE
LifecycleScreen D LifecycleScreen: The current state is ON_START
LifecycleScreen D LifecycleScreen: The current state is ON_RESUME
2.When back button is pressed
LifecycleScreen D LifecycleScreen: The current state is ON_PAUSE
LifecycleScreen D LifecycleScreen: The current state is ON_STOP
3.When Home button is pressed
LifecycleScreen D LifecycleScreen: The current state is ON_PAUSE
LifecycleScreen D LifecycleScreen: The current state is ON_STOP
4.When Recent button is pressed
LifecycleScreen D LifecycleScreen: The current state is ON_PAUSE
LifecycleScreen D LifecycleScreen: The current state is ON_STOP
Whwn you add the following code and run the app
LifecycleEventEffect(Lifecycle.Event.ON_DESTROY) {
Log.d(
"LifecycleScreen",
"LifecycleScreen: The current state is ON_DESTROY"
)
}
we will get this crash report
java.lang.IllegalArgumentException: LifecycleEventEffect cannot be used to listen for Lifecycle.Event.ON_DESTROY, since Compose disposes of the composition before ON_DESTROY observers are invoked.
LifecycleStartEffect&LifecycleResumeEffect
similar to LifecycleEventEffect but it runs only on ON_Start and ON_Resume Event
It takes key that behaves like any other compose keys i.e when key changes , it triggers the code block to run again
when the ON_Stop event triggered , it execute the onStopOrDispose block which helps us to clean up / free resource when this lifecycle event is triggered
when the ON_Pause event triggered , it execute the onPauseOrDispose block
@Composable
fun LifecycleScreen() {
LifecycleStartEffect() {
Log.d(
"LifecycleScreen",
"LifecycleScreen: LifecycleStartEffect"
)
onStopOrDispose {
Log.d(
"LifecycleScreen",
"LifecycleScreen: onStopOrDispose"
)
}
}
LifecycleResumeEffect() {
Log.d(
"LifecycleScreen",
"LifecycleScreen: LifecycleResumeEffect"
)
onPauseOrDispose {
Log.d(
"LifecycleScreen",
"LifecycleScreen: onPauseOrDispose"
)
}
}
}
The Logs are as folows
1.When App launched for first time
LifecycleScreen D LifecycleScreen: LifecycleStartEffect
LifecycleScreen D LifecycleScreen: LifecycleResumeEffect
2.When Home Button is tapped
LifecycleScreen D LifecycleScreen: onPauseOrDispose
LifecycleScreen D LifecycleScreen: onStopOrDispose
3.When Recent button is tapped
LifecycleScreen D LifecycleScreen: onPauseOrDispose
LifecycleScreen D LifecycleScreen: onStopOrDispose
4.When back button is tapped
LifecycleScreen D LifecycleScreen: onPauseOrDispose
LifecycleScreen D LifecycleScreen: onStopOrDispose
LifecycleScreen D LifecycleScreen: onPauseOrDispose
LifecycleScreen D LifecycleScreen: onStopOrDispose
As you can observe in the above log , when back button is pressed , the
onPauseOrDispose
andonStopOrDispose
are executed twice(i think its a bug) in case ofLifecycleStartEffect
andLifecycleResumeEffect
but this is not the case when we useLifecycleEventEffect
Please run the code once in each code block to get better understanding of this lifecycle events and states in compose .
Please leave your comments to improve.
Happy and Enjoy coding
Subscribe to my newsletter
Read articles from Vignesh Prabhu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Vignesh Prabhu
Vignesh Prabhu
I am an Android application developer who is looking for new challenges to solve , love to learn and implement new things in coding