Kotlin Coroutines (The Course)
Course Info
Course Material
- Notes about the course
- Project with exercises
- Why Kotlin Coroutines?
- Why Kotlin Coroutines?
- Coroutines on Android (and other frontend platforms)
- Thread switching
- Callbacks
- RxJava and other reactive streams
- Using Kotlin Coroutines
- Coroutines on the backend
- Conclusion
- Sequence builder
- Sequence builder
- Real-life usages
- Exercise: Factorial sequence
- Exercise: Prime numbers sequence
- How does suspension work?
- How does suspension work?
- Resume
- Resuming with a value
- Resume with an exception
- Suspending a coroutine, not a function
- Summary
- Exercise: Callback function wrappers
- Exercise: Continuation storage
- Coroutines under the hood
- Coroutines under the hood
- Continuation-passing style
- A very simple function
- A function with a state
- A function resumed with a value
- The call stack
- The actual code
- The performance of suspending functions
- Summary
- Exercise: What is stored by a continuation
- Coroutines: built-in support vs library
- Coroutines: built-in support vs library
- Part 2: Kotlin Coroutines library
- Starting coroutine
- Starting coroutine
- Asynchronous coroutine builders
- Blocking coroutine builders
- Structured Concurrency
- Coroutine scope functions
- Summary
- Exercise: Showing user details
- Exercise: Finding the best student
- Exercise: CommentService
- Exercise: mapAsync
- The bigger picture
- The bigger picture
- Coroutine context
- Coroutine context
CoroutineContext
interface- Finding elements in CoroutineContext
- Adding contexts
- Empty coroutine context
- Subtracting elements
- Folding context
- Coroutine context and builders
- Accessing context in a suspending function
- Changing context in suspending functions
- Creating our own context
- Coroutines and thread elements
- Summary
- Exercise: Understanding context propagation
- Exercise: CounterContext
- Dispatchers
- Dispatchers
- Default dispatcher
- Limiting the default dispatcher
- Main dispatcher
- IO dispatcher
- IO dispatcher with a custom pool of threads
- Dispatcher with a fixed pool of threads
- Dispatcher limited to a single thread
- Using virtual threads from Project Loom
- Unconfined dispatcher
- Immediate main dispatching
- Continuation interceptor
- Performance of dispatchers against different tasks
- Summary
- Exercise: DiscNewsRepository
- Exercise: Experiments with dispatchers
- Exercise: Using dispatchers
- Coroutine lifecycle
- Coroutine lifecycle
- What is
Job
? - Coroutine builders create their jobs based on their parent job
- Waiting for children
- Job factory function
- Cancellation
- Cancellation
- Basic cancellation
- How does cancellation work?
- Just one more call
- invokeOnCompletion
- Stopping the unstoppable
suspendCancellableCoroutine
- Summary
- Exception handling
- Exception handling
- Stop breaking my coroutines
- SupervisorJob
- supervisorScope
- Await
- CancellationException does not propagate to its parent
- Coroutine exception handler
- Summary
- Constructing a coroutine scope
- Constructing a coroutine scope
- CoroutineScope factory function
- Constructing a scope on Android
viewModelScope
andlifecycleScope
- Constructing a coroutine on the backend
- Constructing a scope for additional calls
- Summary
- Exercise: NotificationSender
- Exercise: BasePresenter
- The problem with shared state
- The problem with shared state
- Blocking synchronization
- Atomics
- A dispatcher limited to a single thread
- Mutex
- Semaphore
- Summary
- Exercise: UserDownloader
- Exercise: Suspended lazy
- Exercise: mapAsync with concurrency limit
- Testing Kotlin Coroutines
- Testing Kotlin Coroutines
- Testing time dependencies
TestCoroutineScheduler
andStandardTestDispatcher
- runTest
- Background scope
- Testing cancellation and context passing
UnconfinedTestDispatcher
- Using mocks
- Testing functions that change a dispatcher
- Testing what happens during function execution
- Testing functions that launch new coroutines
- Replacing the main dispatcher
- Testing Android functions that launch coroutines
- Setting a test dispatcher with a rule
- Summary
- Exercise: Testing suspending function
- Exercise: Testing mapAsync
- Exercise: Testing NotificationSender
- Exercise: Testing View Model
- Part 3: Channel and Flow
- Channel
- Channel
- Channel types
- On buffer overflow
- On undelivered element handler
- Fan-out
- Fan-in
- Pipelines
- Channels as a communication primitive
- Practical usage
- Summary
- Exercise: Cafeteria simulation
- Select
- Select
- Selecting deferred values
- Selecting from channels
- Summary
- Exercise: raceOf
- Hot and cold data sources
- Hot and cold data sources
- Hot vs cold
- Hot channels, cold flow
- Summary
- Flow introduction
- Flow introduction
- Comparing flow to other ways of representing values
- The characteristics of Flow
- Flow nomenclature
- Real-life use cases
- Summary
- Understanding
Flow
- Understanding
Flow
- Understanding
Flow
- How
Flow
processing works - Flow is synchronous
- Flow and shared states
- Conclusion
- Flow building
- Flow building
- Flow from raw values
- Converters
- Converting a function to a flow
- Flow and Reactive Streams
- Flow builders
- Understanding flow builder
- channelFlow
- callbackFlow
- Summary
- Exercise: Flow utils
- Exercise: All users flow
- Exercise: distinct
- Flow lifecycle functions
- Flow lifecycle functions
- onEach
- onStart
- onCompletion
- onEmpty
- catch
- Uncaught exceptions
retry
- flowOn
- launchIn
- Summary
- Exercise: NewsViewModel
- Flow processing
- Flow processing
map
filter
take
anddrop
- How does collection processing work?
merge
,zip
andcombine
fold
andscan
flatMapConcat
,flatMapMerge
andflatMapLatest
- Distinct until changed
- Terminal operations
- Summary
- Exercise: Flow Kata
- Exercise: MessageService
- SharedFlow and StateFlow
- SharedFlow and StateFlow
- SharedFlow
shareIn
- StateFlow
stateIn
- Summary
- Exercise: LocationService
- Exercise: PriceService
- Exercise: NewsViewModel using shareIn
- Testing flow
- Testing flow
- Transformation functions
- Testing infinite flows
- Determining how many connections were opened
- Testing view models
- Summary
- Exercise: Flow testing
- Part 4: Kotlin Coroutines in practice
- Common use cases
- Common use cases
- Data/Adapters Layer
- Callback functions
- Blocking functions
- Observing with Flow
- Domain Layer
- Concurrent calls
- Flow transformations
- Presentation/API/UI layer
- Creating custom scope
- Using runBlocking
- Working with Flow
- Summary
- Using coroutines from other languages
- Using coroutines from other languages
- Threads on different platforms
- Transforming suspending into non-suspending functions
- Transforming suspend functions into blocking functions
- Transforming suspend functions into callback functions
- Platform-specific options
- Calling suspending functions from other languages
- Flow and Reactive Streams
- Summary
- Launching coroutines vs. suspending functions
- Launching coroutines vs. suspending functions
- Best practices
- Best practices
- Don’t use async with an immediate await
- Use awaitAll
- Suspending functions should be safe to call from any thread
- Use
Dispatchers.Main.immediate
instead ofDispatchers.Main
- Remember to use
yield
in heavy functions - Understand that suspending functions await completion of their children
- Understand that
Job
is not inherited: it is used as a parent - Don’t break structured concurrency
- Use SupervisorJob when creating CoroutineScope
- Consider cancelling scope children
- Before using a scope, consider under which conditions it is cancelled
- Don’t use GlobalScope
- Avoid using
Job
builder, except for constructing a scope - Functions that return
Flow
should not be suspending - Prefer a suspending function instead of Flow when you expect only one value
- Exercise solutions
Instructors
Marcin Moskala is an experienced developer and Kotlin trainer. He is the founder of the Kt. Academy, Kotlin GDE, an official JetBrains partner for teaching Kotlin, and author of the books Effective Kotlin, Kotlin Coroutines, and Android Development with Kotlin.
The Leanpub 60 Day 100% Happiness Guarantee
Within 60 days of purchase you can get a 100% refund on any Leanpub purchase, in two clicks.
Now, this is technically risky for us, since you'll have the book or course files either way. But we're so confident in our products and services, and in our authors and readers, that we're happy to offer a full money back guarantee for everything we sell.
You can only find out how good something is by trying it, and because of our 100% money back guarantee there's literally no risk to do so!
So, there's no reason not to click the Add to Cart button, is there?
See full terms...
80% Royalties. Earn $16 on a $20 book.
We pay 80% royalties. That's not a typo: you earn $16 on a $20 sale. If we sell 5000 non-refunded copies of your book or course for $20, you'll earn $80,000.
(Yes, some authors have already earned much more than that on Leanpub.)
In fact, authors have earnedover $13 millionwriting, publishing and selling on Leanpub.
Learn more about writing on Leanpub
Free Updates. DRM Free.
If you buy a Leanpub book, you get free updates for as long as the author updates the book! Many authors use Leanpub to publish their books in-progress, while they are writing them. All readers get free updates, regardless of when they bought the book or how much they paid (including free).
Most Leanpub books are available in PDF (for computers) and EPUB (for phones, tablets and Kindle). The formats that a book includes are shown at the top right corner of this page.
Finally, Leanpub books don't have any DRM copy-protection nonsense, so you can easily read them on any supported device.
Learn more about Leanpub's ebook formats and where to read them