Skip to content

Instantly share code, notes, and snippets.


Zac Sweers ZacSweers

View GitHub Profile
ZacSweers / OkioAtomicFile.kt
Created Sep 16, 2018
Okio/AtomicFile interop kotlin extensions
View OkioAtomicFile.kt
import android.util.AtomicFile
import okio.Buffer
import okio.Sink
import okio.sink
import okio.source
fun AtomicFile.source() = openRead().source()
ZacSweers / GuardTest.kt
Last active Sep 14, 2018
Demo of how the Nothing type in Kotlin can allow a Swift-style guard function
View GuardTest.kt
import org.junit.Test
inline fun <T> guard(receiver: T?, block: () -> Nothing): T {
if (receiver == null) {
return receiver
Scheduler asyncMainThreadScheduler = AndroidSchedulers.from(Looper.getMainLooper(), true);
RxAndroidPlugins.setInitMainThreadSchedulerHandler(callable -> asyncMainThreadScheduler);
// Or if the default scheduler is already initialiazed
RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> asyncMainThreadScheduler);
View AsyncMessagingExample.kt
val asyncMainThreadScheduler = AndroidSchedulers.from(Looper.getMainLooper(), true)
RxAndroidPlugins.setInitMainThreadSchedulerHandler { asyncMainThreadScheduler }
// Or if the default scheduler is already initialiazed
RxAndroidPlugins.setMainThreadSchedulerHandler { asyncMainThreadScheduler }
View Complex.kt
@JsonClass(generateAdapter = true)
data class Foo<T>(
@Json(name = "barString") val bar: String,
val defaultValue: Int = 0,
val nullableString: String?,
val typeParam: T? = null,
val tList: List<T>
// Generated by Moshi Kotlin Code Gen
View Simple.kt
// Sample JSON
// { "bar": "hello world" }
// The Foo class
@JsonClass(generateAdapter = true)
data class Foo(
val bar: String
// Generated by Moshi Kotlin Code Gen


To keep the arguments and examples to the point there are few helpful rules:

  • No abstract examples/arguments. These cause the discussion to lose focus and make examples harder to follow. The example/argument must be traceable to a real-world problem - ___ is intended to solve real problems, not imaginary ones.
  • Examples must show the full complexity of the problem domain. Simplified examples trivialize the problems and the solutions intended to solve those simplified examples may not work for the complex problems.
  • Examples of problematic ___ code must be the “best way” of writing the code in ___ - if it can be improved then the improved version should be used instead.
  • Arguments must be straight to the point and as concise as possible.
  • Arguments should take the point of view of an average programmer - not the über-programmer who doesn’t make design mistakes.
ZacSweers / Sample.kt
Created Nov 19, 2017
Stars in notifications
View Sample.kt
fun notification() {
val channelId = "stars"
val notificationManager = activity.getSystemService<NotificationManager>()
val channels = notificationManager.notificationChannels
if (channels.none { == channelId }) {
channelId, "stars", NotificationManager.IMPORTANCE_HIGH)
.apply {
description = "Demo"
ZacSweers / ReusableInjection.kt
Last active Oct 2, 2017
Reusable injections
View ReusableInjection.kt
class Parent {
// Somewhere in here, a lot of external service modules are included and contribute their `Service` impls to this multibinding
@Inject lateinit var services: Map<String, Provider<Service>>
fun showChild() {
addChildController(serviceKey = "barServiceKey") // Key into the services map
ZacSweers / OffsetsWithDirection.kt
Last active Feb 21, 2019
Observable stream of AppBarLayout offsets + scroll direction from
View OffsetsWithDirection.kt
* Here we want to get the appbar offset changes paired with the direction it's moving and
* using RxBinding's great `offsetChanges` API to make an rx Observable of this. The first
* part buffers two while skipping one at a time and emits y delta pairs (cur and prev). Second
* part is just a simple map to pair the offset with the resolved scroll direction comparing
* to the previous offset. This gives us a nice stream of (offset, direction) emissions.
* Note that the filter() is important if you manipulate child views of the ABL. If any child
* view requests layout again, it will trigger an emission from the offset listener with the
* same value as before, potentially causing measure/layout/draw thrashing if your logic
You can’t perform that action at this time.