PausingDispatcherKt

public final class PausingDispatcherKt


Summary

Public methods

static final @NonNull T

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.CREATED state.

static final @NonNull T

Runs the given block when the Lifecycle is at least in Lifecycle.State.CREATED state.

static final @NonNull T

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.RESUMED state.

static final @NonNull T

Runs the given block when the Lifecycle is at least in Lifecycle.State.RESUMED state.

static final @NonNull T

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.STARTED state.

static final @NonNull T

Runs the given block when the Lifecycle is at least in Lifecycle.State.STARTED state.

static final @NonNull T
<T extends Object> PausingDispatcherKt.whenStateAtLeast(
    @NonNull Lifecycle receiver,
    @NonNull Lifecycle.State minState,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block on a CoroutineDispatcher that executes the block on the main thread and suspends the execution unless the Lifecycle's state is at least minState.

Public methods

PausingDispatcherKt.whenCreated

@NonNull
public static final T <T extends Object> PausingDispatcherKt.whenCreated(
    @NonNull LifecycleOwner receiver,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.CREATED state.

See also
whenStateAtLeast

for details

PausingDispatcherKt.whenCreated

@NonNull
public static final T <T extends Object> PausingDispatcherKt.whenCreated(
    @NonNull Lifecycle receiver,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block when the Lifecycle is at least in Lifecycle.State.CREATED state.

See also
whenStateAtLeast

for details

PausingDispatcherKt.whenResumed

@NonNull
public static final T <T extends Object> PausingDispatcherKt.whenResumed(
    @NonNull LifecycleOwner receiver,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.RESUMED state.

See also
whenStateAtLeast

for details

PausingDispatcherKt.whenResumed

@NonNull
public static final T <T extends Object> PausingDispatcherKt.whenResumed(
    @NonNull Lifecycle receiver,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block when the Lifecycle is at least in Lifecycle.State.RESUMED state.

See also
whenStateAtLeast

for details

PausingDispatcherKt.whenStarted

@NonNull
public static final T <T extends Object> PausingDispatcherKt.whenStarted(
    @NonNull LifecycleOwner receiver,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.STARTED state.

See also
whenStateAtLeast

for details

PausingDispatcherKt.whenStarted

@NonNull
public static final T <T extends Object> PausingDispatcherKt.whenStarted(
    @NonNull Lifecycle receiver,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block when the Lifecycle is at least in Lifecycle.State.STARTED state.

See also
whenStateAtLeast

for details

PausingDispatcherKt.whenStateAtLeast

@NonNull
public static final T <T extends Object> PausingDispatcherKt.whenStateAtLeast(
    @NonNull Lifecycle receiver,
    @NonNull Lifecycle.State minState,
    @NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block
)

Runs the given block on a CoroutineDispatcher that executes the block on the main thread and suspends the execution unless the Lifecycle's state is at least minState.

If the Lifecycle moves to a lesser state while the block is running, the block will be suspended until the Lifecycle reaches to a state greater or equal to minState.

Note that this won't effect any sub coroutine if they use a different CoroutineDispatcher. However, the block will not resume execution when the sub coroutine finishes unless the Lifecycle is at least in minState.

If the Lifecycle is destroyed while the block is suspended, the block will be cancelled which will also cancel any child coroutine launched inside the block.

If you have a try finally block in your code, the finally might run after the Lifecycle moves outside the desired state. It is recommended to check the Lifecycle.getCurrentState before accessing the UI. Similarly, if you have a catch statement that might catch CancellationException, you should check the Lifecycle.getCurrentState before accessing the UI. See the sample below for more details.

// running a block of code only if lifecycle is STARTED
viewLifecycle.whenStateAtLeast(Lifecycle.State.STARTED) {
// here, we are on the main thread and view lifecycle is guaranteed to be STARTED or RESUMED.
// We can safely access our views.
loadingBar.visibility = View.VISIBLE
try {
// we can call any suspend function
val data = withContext(Dispatchers.IO) {
// this will run in IO thread pool. It will keep running as long as Lifecycle
// is not DESTROYED. If it is destroyed, this coroutine will be cancelled as well.
// However, we CANNOT access Views here.

// We are using withContext(Dispatchers.IO) here just for demonstration purposes.
// Such code should live in your business logic classes and your UI should use a
// ViewModel (or similar) to access it.
api.getUser()
}
// this line will execute on the main thread and only if the lifecycle is in at least
// STARTED state (STARTED is the parameter we've passed to whenStateAtLeast)
// Because of this guarantee, we can safely access the UI again.
loadingBar.visibility = View.GONE
nameTextView.text = user.name
lastNameTextView.text = user.lastName
} catch(ex : UserNotFoundException) {
// same as above, this code can safely access UI elements because it only runs if
// view lifecycle is at least STARTED
loadingBar.visibility = View.GONE
showErrorDialog(ex)
} catch(th : Throwable) {
// Unlike the catch statement above, this catch statements it too generic and might
// also catch the CancellationException. Before accessing UI, you should check isActive
// or lifecycle state
if (viewLifecycle.currentState >= Lifecycle.State.STARTED) {
// here you can access the view because you've checked the coroutine is active
}
} finally {
// in case of cancellation, this line might run even if the Lifecycle is not DESTROYED.
// You cannot access Views here unless you check `isActive` or lifecycle state
if (viewLifecycle.currentState >= Lifecycle.State.STARTED) {
// safe to access views
} else {
// not safe to access views
}
}
}
Parameters
@NonNull Lifecycle.State minState

The desired minimum state to run the block.

@NonNull SuspendFunction1<@NonNull CoroutineScope, @NonNull T> block

The block to run when the lifecycle is at least in minState.

Returns
T The return value of the [block]