Dalek is a tiny (~10 LOC) finite state machine that helps you manage the UI state of your app when running async/breakable tasks.
It's powered by Coroutines Flow and works on Android & JVM.
Daleks are a fictional extraterrestrial race of mutants portrayed in Doctor Who.
They are creatures that live inside a tank-like robotic shell, and this is basically how this library works: your code (the "creature") is wrapped and executed inside a state machine (the "robotic shell").
"EXTERMINATE! EXTERMINATE! EXTERMINATE!"
(Any Dalek will say that)
Let's imagine the following scenario: you need to retrieve a Post
object from a REST API, something like:
class PostRepository {
suspend fun getPost(id: String): Post {
// async api call
// serialization
// error handling
}
}
It's an asynchronous operation that can take a while to complete and can fail (TimeoutException
, IOException
, SerializationException
...). But wait, there's more: you need to keep the UI updated so your user knows what's going on.
This is a nightmare, right? Calm down! Dalek is here to help 🤖
To start using Dalek, you just need to wrap your existing code inside it.
Dalek will run your code inside a suspend fun
and return a Flow<DalekEvent<T>>
, where T
is the output of your code (you can return null
, Unit
and Any
, I won't judge you).
class MyViewModel(private val repository: PostRepository) : ViewModel() {
fun getPost(id: String): Flow<DalekEvent<Post>> =
Dalek(Dispatchers.IO) {
repository.getPost(id)
}
}
Dalek will emit the following events:
Start
: always emittedSuccess(value: T)
: only emitted when your code is successfully executedFailure(exception: Throwable)
: only emitted when an exception is thrownFinish
: always emitted
class MyActivity : AppCompatActivity() {
private fun loadPost(id: String) {
viewModel.getPost(id)
.collectIn(lifecycleScope) { event ->
when (event) {
is Start -> setLoading(true)
is Success -> showPost(event.value)
is Failure -> showError(event.exception)
is Finish -> setLoading(false)
}
}
}
}
- Add the JitPack repository in your root build.gradle at the end of repositories:
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
- Next, add the library to your module:
dependencies {
implementation "com.github.adrielcafe:dalek:$currentVersion"
}