Skip to content

Instantly share code, notes, and snippets.


Zak Taccardi ZakTaccardi

View GitHub Profile
ZakTaccardi / LibsAccessor.kt
Created Aug 29, 2022
Migrate to version catalogs now!
View LibsAccessor.kt
import myapp.dependencyCatalogs.LibsCatalogExtension
import org.gradle.api.Project
import org.gradle.kotlin.dsl.the
// this file is in `buildSrc` in the root package, so `libs` will point to this function or the generated `libs` from the `.toml` file
* Wrapper with no package name to have projects automatically pick up [LibsCatalogExtension] when this function exists.
* The generated version accessors is [].
ZakTaccardi / LocalPropertySupport.kt
Created Jan 3, 2022
`` and project level gradle properties support for Configuration Cache
View LocalPropertySupport.kt
import org.gradle.api.Project
import org.gradle.api.file.ProjectLayout
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import org.gradle.kotlin.dsl.of
import java.util.Properties
ZakTaccardi / FunctionInterceptionExample.kt
Created Dec 16, 2020
Function Interception (composition)
View FunctionInterceptionExample.kt
* An abstraction around a 3rd party SDK that does some magic to
* identify if a user is a bot or not.
* The real implementation may have direct Android dependencies,
* so being able to swap this out is useful for unit testing
interface VendorSdk {
suspend fun isUserABot(): Boolean
ZakTaccardi / SimpleMvi.kt
Last active May 22, 2020
Simple MVI coroutine example
View SimpleMvi.kt
interface MviViewModel<in I, out VS, out SE> {
val states: Flow<VS>
val sideEffects: Flow<SE>
fun send(intention: I)
class SimpleViewModel(scope: CoroutineScope) : MviViewModel<Intention, State, SideEffect> {
private val _states = MutableStateFlow(0) // this is an always have an initial state example
private val _sideEffects = Channel<SideEffect>(capacity = Channel.UNLIMITED) // we don't want the actor coroutine to ever suspend, in case there is no UI consuming
ZakTaccardi / 1-ManualFragment.kt
Created May 20, 2020
A practical example on why Composition over Inheritance matters for your codebase
View 1-ManualFragment.kt
* Solution 1 = Manual
internal class MyManualFragment(
private val viewModel: ViewModel
) : Fragment() {
private var startedScope: CoroutineScope? = null
override fun onStart() {
View LifecycleScopeExtensionsInternal.kt
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.CoroutineScope
internal class ViewLifecycleScopeImpl(
private val fragment: Fragment
) : ViewLifecycleScope {
View NoInitialStateFlow.kt
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
* A variant of [StateFlow] that allows an initial state
interface NoInitialStateFlow<T> : Flow<T> {
View StateActor.kt
import kotlinx.coroutines.CompletionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.flow.Flow
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
interface StateActor<S, I> : SendChannel<I> {
View DontBreakTheChainTest.kt
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Test
import kotlin.coroutines.ContinuationInterceptor
ZakTaccardi /
Created Apr 22, 2020
Don't break the chain

PSA, don’t construct new CoroutineScopes and break structured concurrency in your classes.

class TransactionsDb(dispatchers: MyDispatchers) {
  private val scope = CoroutineScope(

This can cause tests to pass when an exception is thrown.