Merge "Quick cancellation of effect scopes" into androidx-main am: dd48cf473c
Original change: https://android-review.googlesource.com/c/platform/frameworks/support/+/2583774
Change-Id: I6bdd1a9d7d44818d3c19888318356137bb21e8f5
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
index 1254875..9efcc11 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
@@ -22,6 +22,7 @@
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlin.coroutines.EmptyCoroutineContext
+import kotlinx.coroutines.CancellationException
/**
* Schedule [effect] to run when the current composition completes successfully and applies
@@ -284,17 +285,18 @@
private var job: Job? = null
override fun onRemembered() {
+ // This should never happen but is left here for safety
job?.cancel("Old job was still running!")
job = scope.launch(block = task)
}
override fun onForgotten() {
- job?.cancel()
+ job?.cancel(LeftCompositionCancellationException())
job = null
}
override fun onAbandoned() {
- job?.cancel()
+ job?.cancel(LeftCompositionCancellationException())
job = null
}
}
@@ -384,6 +386,12 @@
remember(key1, key2, key3) { LaunchedEffectImpl(applyContext, block) }
}
+private class LeftCompositionCancellationException : CancellationException(
+ "The coroutine scope left the composition"
+) {
+ override fun fillInStackTrace(): Throwable = this
+}
+
/**
* When [LaunchedEffect] enters the composition it will launch [block] into the composition's
* [CoroutineContext]. The coroutine will be [cancelled][Job.cancel] and **re-launched** when
@@ -416,11 +424,11 @@
}
override fun onForgotten() {
- coroutineScope.cancel()
+ coroutineScope.cancel(LeftCompositionCancellationException())
}
override fun onAbandoned() {
- coroutineScope.cancel()
+ coroutineScope.cancel(LeftCompositionCancellationException())
}
}