This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Analogue of [runCatching] with retry, delay & logging added. | |
* Re-throws CancellationException to avoid the need to explicitly skip it in [onFailure]. | |
* Intervals are calculated since previous failure. | |
*/ | |
@ExperimentalTime | |
suspend fun <T> runRetrying( | |
times: Int, | |
interval: Duration, | |
name: String, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private const val TAG = "MainActivity" | |
class MainActivity : AppCompatActivity(R.layout.activity_main) { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
getString(R.string.str10).let { | |
Log.i(TAG, "str '${it.replace("\n", "\\n")}', raw '$it'") | |
findViewById<TextView>(R.id.text).apply { | |
text = it |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline fun <R, T> Result<T>.flatMap(transform: (T) -> Result<R>): Result<R> = | |
fold({ transform(it) }, { Result.failure(it) }) | |
fun main() { | |
getUserInput() | |
.flatMap { input -> parseInput(input) } | |
.flatMap { numbers -> calculateMax(numbers) } | |
.onSuccess { maxNumber -> println("max: $maxNumber") } | |
.onFailure { throwable -> throwable.printStackTrace() } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import androidx.appcompat.app.AppCompatActivity | |
import androidx.fragment.app.DialogFragment | |
import androidx.fragment.app.Fragment | |
import androidx.lifecycle.DefaultLifecycleObserver | |
import androidx.lifecycle.Lifecycle | |
import androidx.lifecycle.LifecycleOwner | |
import androidx.viewbinding.ViewBinding |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Coroutine-based solution for delayed and periodic work. May fire once (if [interval] omitted) | |
* or periodically ([startDelay] defaults to [interval] in this case), replacing both | |
* `Observable.timer()` & `Observable.interval()` from RxJava. | |
* | |
* In contrast to RxJava, intervals are calculated since previous run completion; this is more | |
* convenient for potentially long work (prevents overlapping) and does not suffer from queueing | |
* multiple invocations in Doze mode on Android. | |
* | |
* Dispatcher is inherited from scope, may be overridden via [context] parameter. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Starts collecting a flow when the lifecycle is started, and **cancels** the collection on stop. | |
* 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 action: suspend (T) -> Unit | |
) { | |
object : DefaultLifecycleObserver { |