Skip to content

Commit

Permalink
Merge pull request #3 from peterLaurence/launchWhen
Browse files Browse the repository at this point in the history
Add launchWhenX variants, and deprecated former API
  • Loading branch information
psteiger authored Jan 24, 2021
2 parents 088f9c9 + 446a677 commit 9f62551
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
kotlin_version = '1.4.20'
kotlin_version = '1.4.21'
coroutines_version = '1.4.1'
lifecycle_version = '2.2.0'
}
Expand All @@ -10,7 +10,7 @@ buildscript {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.0-alpha16"
classpath 'com.android.tools.build:gradle:4.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// NOTE: Do not place your application dependencies here; they belong
Expand Down
6 changes: 3 additions & 3 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Mon Nov 23 13:27:57 BRT 2020
#Sun Jan 24 09:41:36 CET 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
92 changes: 87 additions & 5 deletions lib/src/main/java/com/freelapp/flowlifecycleobserver/Observer.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("unused")

package com.freelapp.flowlifecycleobserver

import androidx.lifecycle.DefaultLifecycleObserver
Expand All @@ -6,10 +8,32 @@ import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
* Utility extension function to start collecting a flow when the lifecycle is started,
* and *cancel* the collection on stop, with a custom collector.
* This is different from `lifecycleScope.launchWhenStarted{ flow.collect{..} }`, in which case the
* coroutine is just suspended on stop.
*/
inline fun <reified T> Flow<T>.collectWhileStarted(
lifecycleOwner: LifecycleOwner,
noinline collector: suspend (T) -> Unit
) {
ObserverWhileStartedImpl(lifecycleOwner, this, collector)
}

/**
* Utility extension function on [Flow] to start collecting a flow when the lifecycle is started,
* and *cancel* the collection on stop.
*/
inline fun <reified T> Flow<T>.collectWhileStartedIn(
lifecycleOwner: LifecycleOwner
) {
ObserverWhileStartedImpl(lifecycleOwner, this, {})
}

@PublishedApi
internal class ObserverImpl<T> (
internal class ObserverWhileStartedImpl<T>(
lifecycleOwner: LifecycleOwner,
private val flow: Flow<T>,
private val collector: suspend (T) -> Unit
Expand All @@ -18,7 +42,7 @@ internal class ObserverImpl<T> (
private var job: Job? = null

override fun onStart(owner: LifecycleOwner) {
job = owner.lifecycleScope.launch {
job = owner.lifecycleScope.launchWhenStarted {
flow.collect {
collector(it)
}
Expand All @@ -35,15 +59,73 @@ internal class ObserverImpl<T> (
}
}

/**
* Utility extension function to start collecting a flow when the lifecycle is resumed,
* and *cancel* the collection on stop, with a custom collector.
* This is different from `lifecycleScope.launchWhenResumed{ flow.collect{..} }`, in which case the
* coroutine is just suspended on stop.
*/
inline fun <reified T> Flow<T>.collectWhileResumed(
lifecycleOwner: LifecycleOwner,
noinline collector: suspend (T) -> Unit
) {
ObserverWhileResumedImpl(lifecycleOwner, this, collector)
}

/**
* Utility extension function on [Flow] to start collecting a flow when the lifecycle is resumed,
* and *cancel* the collection on stop.
*/
inline fun <reified T> Flow<T>.collectWhileResumedIn(
lifecycleOwner: LifecycleOwner
) {
ObserverWhileResumedImpl(lifecycleOwner, this, {})
}

@PublishedApi
internal class ObserverWhileResumedImpl<T>(
lifecycleOwner: LifecycleOwner,
private val flow: Flow<T>,
private val collector: suspend (T) -> Unit
) : DefaultLifecycleObserver {

private var job: Job? = null

override fun onResume(owner: LifecycleOwner) {
job = owner.lifecycleScope.launchWhenResumed {
flow.collect {
collector(it)
}
}
}

override fun onPause(owner: LifecycleOwner) {
job?.cancel()
job = null
}

init {
lifecycleOwner.lifecycle.addObserver(this)
}
}

@Deprecated(
"Old alias for collectWhileStarted",
ReplaceWith("collectWhileStarted")
)
inline fun <reified T> Flow<T>.observe(
lifecycleOwner: LifecycleOwner,
noinline collector: suspend (T) -> Unit
) {
ObserverImpl(lifecycleOwner, this, collector)
collectWhileStarted(lifecycleOwner, collector)
}

@Deprecated(
"Old alias for collectWhileStartedIn",
ReplaceWith("collectWhileStartedIn")
)
inline fun <reified T> Flow<T>.observeIn(
lifecycleOwner: LifecycleOwner
) {
ObserverImpl(lifecycleOwner, this, {})
collectWhileStartedIn(lifecycleOwner)
}

0 comments on commit 9f62551

Please sign in to comment.