Skip to content

Commit

Permalink
Add Lifecycle.doOnEvent.
Browse files Browse the repository at this point in the history
This is a one-shot callback for work that needs to be done in a
specific lifecycle state.

Use case I had for this was waiting for an app the be in a started
state before performing a Fragment transaction.

For example:
```
// In Activity.onCreate()
viewModel.events()
    .onEach { event ->
       if (event is Event.FragmentNavigate) {
           // User might have backgrounded the app at this point, so
           // wait til it's safe to navigate.
           lifecycle.doOnEvent(Lifecycle.Event.ON_START) {
               supportFragmentManager.commit {
                   replace(android.R.id.content, MyFragment()
               }
           }
       }
    }
    .launchIn(lifecycleScope)
```

There exists Lifecycle.whenStarted which can achieve the same as the above,
but it needlessly launches a coroutine, and the API is documented that it'll
be removed entirely in a future update.
  • Loading branch information
Nick Rose committed Aug 8, 2021
1 parent 374bc58 commit b38f3a5
Showing 1 changed file with 18 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.crazylegend.lifecycle

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

Expand Down Expand Up @@ -60,3 +64,15 @@ fun AppCompatActivity.repeatingJobOnStarted(block: suspend CoroutineScope.() ->
fun AppCompatActivity.repeatingJobOnResumed(block: suspend CoroutineScope.() -> Unit) {
lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED, block) }
}

fun Lifecycle.doOnEvent(which: Lifecycle.Event, block: () -> Unit) {
val observer = object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (which != event) return
removeObserver(this)
block()
}
}

addObserver(observer)
}

0 comments on commit b38f3a5

Please sign in to comment.