Kotlin Coroutines (The Course)
Course Info
This course includes 1 attempt.
This is a practical course, that shows everything with examples and focuses on real-life use cases. As this technology is already widely used on Android and backend applications, we will see how we can use it there and what the best practices are.
Course Material
- Notes about the course
- Project with exercises
- Part 1: Understanding 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
- Real-life usages
- Exercise: Factorial sequence
- Exercise: Prime numbers sequence
- How does suspension work?
- A game analogy
- Suspending functions
- Your first suspension
- What is stored in the continuation?
- Delaying a coroutine
- 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
- 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
- Part 2: Kotlin Coroutines library
- Starting coroutines
- 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
- 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
- Default dispatcher
- Limiting the default dispatcher
- Main dispatcher
- IO dispatcher
- Dispatcher with a custom limit
- 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 when executing different tasks
- Summary
- Exercise: Using dispatchers
- Exercise: DiscNewsRepository
- Exercise: Experiments with dispatchers
- Job and coroutine lifecycle
- Job and relationships
- Coroutine lifecycle
- Awaiting job completion
- The Job factory function
- Synchronizing coroutines
- Summary
- Cancellation
- Basic cancellation
- The
finally
block - invokeOnCompletion
- Cancellation of children
- Cancellation in a coroutine scope
- Just one more call
- Stopping the unstoppable
- CancellationException does not propagate to its parent
- withTimeout
suspendCancellableCoroutine
- Summary
- Exercise: Correct mistakes with cancellation
- Exception handling
- Exceptions and structured concurrency
- SupervisorJob
- Do not use SupervisorJob as a builder argument
- supervisorScope
- Do not use
withContext(SupervisorJob())
- Exceptions and await call
CoroutineExceptionHandler
- Summary
- Constructing a coroutine scope
- CoroutineScope factory function
- Constructing a background scope
- Constructing a scope on Android
- Summary
- Exercise: NotificationSender
- Exercise: BasePresenter
- The problem with shared state
- Blocking synchronization
- Atomics
- A dispatcher limited to a single thread
- Mutex
- Semaphore
- Summary
- Exercise: UserDownloader
- Exercise: CompanyDetailsRepository
- 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 a suspending function
- Exercise: Testing mapAsync
- Exercise: Testing the NotificationSender class
- Exercise: Testing a View Model
- Part 3: Channel and Flow
- Channel
- Channel types
- On buffer overflow
- On undelivered element handler
- Fan-out
- Fan-in
- Pipelines
- Practical usage
- Summary
- Select
- Selecting deferred values
- Selecting from channels
- Summary
- Exercise: raceOf
- Hot and cold data sources
- Hot vs cold
- Hot channels, cold flow
- Summary
- 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
- How
Flow
processing works - Flow is synchronous
- Flow and shared state
- Conclusion
- 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
- onEach
- onStart
- onCompletion
- onEmpty
- catch
- Uncaught exceptions
retry
- flowOn
- launchIn
- Summary
- Exercise: NewsViewModel
- Flow processing
map
filter
take
anddrop
- How does collection processing work?
merge
,zip
andcombine
merge
,zip
andcombine
fold
andscan
fold
andscan
flatMapConcat
,flatMapMerge
andflatMapLatest
flatMapConcat
,flatMapMerge
andflatMapLatest
- Distinct until changed
- Distinct until changed
- Terminal operations
- Terminal operations
- Summary
- Exercise: ProductService
- Exercise: Flow Kata
- Exercise: MessageService
- SharedFlow and StateFlow
- SharedFlow
shareIn
- StateFlow
stateIn
- Summary
- Exercise: LocationService
- Exercise: PriceService
- Exercise: NewsViewModel using shareIn
- 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
- Data/Adapters Layer
- Data/Adapters Layer
- Callback functions
- Blocking functions
- Observing with Flow
- Domain Layer
- Domain Layer
- Concurrent calls
- Flow transformations
- Presentation/API/UI layer
- Presentation/API/UI layer
- Creating custom scope
- Using runBlocking
- Working with Flow
- Summary
- Summary
- 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
- 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...
Earn $8 on a $10 Purchase, and $16 on a $20 Purchase
We pay 80% royalties on purchases of $7.99 or more, and 80% royalties minus a 50 cent flat fee on purchases between $0.99 and $7.98. You earn $8 on a $10 sale, and $16 on a $20 sale. So, if we sell 5000 non-refunded copies of your book 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