hey everybody and welcome to
our very first andray colon I'm Karen engineer on the
Android Developer Relations team Hi, everyone. I'm also an engineer on the
developer relations team. Thank you so much for joining
us today in this Andre Courtland series we will be live
coding different programming challenges you will face as
you progress as an Android developer so here we are so
that you can get a better understanding of how we
recommend approaching those challenges Yeah so as
menos coding along I feel free to pull back in the
Studio and also follow along or you could feel free to just
watch and do the Colab yourself a little later. We're also going to be
looking at the live chat. So if you have any
questions, feel free to ask it in the
live chat and we'll try to answer as many
questions as we can. Thank you so much. So the first topic
for this series is going to be carotids so
I'm going to be calling here on my laptop so please feel
free to go along with me or actually with us and
ask as many questions as you have will be very
happy to answer them. So we move to the
laptop here I hope it's being shown
right time Yep Yeah and we already have a
great question coming in so Zina's is this going to be
for someone who knows nothing about coroutines Yeah,
definitely joinder right. So we are going
to assume nothing so basically we're going to
start from scratch assuming that you have some sort
of Android background here like a little bit what we
are trying to achieve things like what happened when you
know something is running on the thread but
regarding Kirby's you don't need to know anything
right now we will explain everything in this session but
thank you for the question cool so basically whenever I want to
learn about a specific topic. And in this case,
this is going to be crudites I go to a
developer the dondre and I search for the topic, so in this
case is going to be A Let's say groupings for example. So here basically the top search
is going to be cutting corners and andred which is
actually our documentation. And as you can see we have a
pretty detailed guide so we have, for example
like features how to execute things in the
background fit and perform this we have also a
visual guide for this or we have different pages. If you see here
on the right side of the screen with
a few things that are going to be quite useful. So for example, we
have the best practice is we have additional resources
we have things like flows as well that we might not
get into in the session but they are definitely
good resources to check out on your free time
so basically we're going to be talking about
groupings and actually groupings and you take a
look here is our recommended solution for asynchronous
programming or mandry that's why because in the past
I think asynchronous programming it's quite a complex
topic to face and really simplify
how we approach and solve these
asynchronous tasks. And one of the features
to mention for example, is that they are lightweight
and for example, you can run many groupings
on a single thread because they don't actually
block before they suspend the execution and
we will see later and we will understand
better in a second it actually has lower chances
of creating memory leaks because it has something called
structured concurrency where all these operations block of
code that you're going to run I want to execute
in a specific scope and whenever it does
goes away for example, you are navigating
away from the screen. All those operations are
going to be canceled also has a pretty good routine
cancellation support this is something that other
alternatives like callbacks suffer from and callbacks
is quite difficult to handle cancellation properly including
actually like provides an easy way to do so
and my favorite here is like interation so we
have a lot of things covered with kolbeinn so we
have a new model we have room support
for the database we have so many things. For example WorkManager as well. So we will see how everything
plays along pretty well. So if you listen
through the guide you will see like old
explanation this is kind of a little
bit of theory behind it but actually today we want to
complete or actually go through the kulluk either no
we have time enough to complete it all
but something I want to mention for
example, if you're really new to current inside
there are some people we have this additional resources
page where we have things like specific topics like
Basics cancellation exceptions and there is these
first things first blog post that actually teaches the
basic concepts I'm probably like I'm going to
leave it open in case, we have to come back to this
later because it explains things like what I
put in context which I call the scope and all
that OK stop talking. Let's go to a bit. So leave open as well. So basically now
we're going to go through the collapse
of something we can do is try to search for
the Europeans Columbia basically if I do that,
I get a few results. So we're going to go
through the basics, which is this result here. But we have multiple things
collapse apart from the basics that we are going
to go through today we have the advanced
things collapse which is this one here. And also from the
training courses we have another one which is
building a Kotlin extensions library comes up and
this one is basically whenever you have
nonpolluting code, how to create a bridge
to convert it to crupi and having like a more idiomatic
version of that specific API so you're whispering
APIs like to spend suspendCancellableCoroutine
grouping or call backflow that we
obviously don't have the time to cover today. But Yeah let's open the club I
found this to be as well open. So if you want to go along
with me, feel free to do so. And so here basically good
that is just a self-paced guide for you to actually code
and run an application that is going to teach you
about a specific topic. So this one is about
confidence in your Android app. And basically collapse
follow the same structure and the first one is going to
be like before you begin or kind of like an introduction
section and here we are just trying to set
expectations like OK this is your first
introduction to a specific is like what I'm going to learn
I'm in the right place or not. So here am I going
to say, OK, we're going to go through this
going to learn about that some prerequisites. For example like you're familiar
with the model repository layer and all that room database
you are familiar or have some experience with Gotlieb and
basically the things that you will do too much we have this
question where someone was wondering what exactly is
cowritten so what kind of use cases are proteins useful and
should they be thinking about Currey teams as a replacement
for arc's Java or Kotlin what is the official guidance here
Yeah so this is our recommended solution for asynchronous
programming and when we talk about asynchronous programming
it's basically kind of the opposite of synchronous
programming synchronous wherever you want to run
something synchronises like basically I want
this to be run right now I don't want to wait for
this asynchronously it means that I want to run something
that probably doesn't need to go to the unrated
UI threat of course, because there are some
operations that need to happen in the background. So that we don't block the
UI because we want to have a responsive application. So with synchronous
programming it's like OK we might
want to run something on a different thread but also
I want to execute something on this same thread but I
don't want it to happen right now or better said
I don't mind if it's executed like 15 seconds later
because something else is being executed there's basically
a way to run a piece of code as we will see that could
even happen like in any threat but doesn't need to
happen right now. And it doesn't need to block
this right I hope that's clear and regarding the
next level a solution flow for a synchronous
programming and it was pretty popular in
the past whenever things weren't there but a Google or an Android
we recommend using croutons for this specific use
case because as it was saying like all our
Jetpack libraries are really well integrated with grouping's
cool Thanks for the question. OK so getting set up this is
another section in our clubs that pretty much all
our clubs do the same and I'm here basically tells
you how to download the code and how the code is
structured so for example, the curtains codelab we
will see later in the Studio it has a project that you
download and in the project there are two little
modules with we start echoed another one with the
finished school just to make sure that you want
to make sure that you follow the code properly or
if you at the start you can see the solution there
but this set up totally depends on the author and also the
project that we are in charge and we are trying to solve
some of these specific use case this set up works pretty well. And that's what we
have been using now OK, let's move on
to another Studio so basically here we are
going to see an application. This is called that whenever
you tap on the screen a message is going
to be displayed. So I have here in
the Studio that I can run the up side as I was
saying here on the Studio we have the start package
that the module with all our code in case, we wanted to
check out the solution I would go here through the
finished code module and I also have my
emulator open so here I can see the application whenever
I tap on the screen it's going to load you are going to see
the loading spinner there and then I'm just going to
count how many times you've been tapping on the screen. So here says to
tabs and then kind of the title or the message on
the screen is going to change. So basically what we
are going to do we're going to see later in the
code that asynchronously we are going to make a request
to update the number of times to that we've been tapping on
the screen that's going to be communicated to the UI but also
something else is going to be allowed in the background. And if we take a look
here that comes up it explains how the
app is architecture and this is kind of follows kind
of the classical pattern where we are going to have the
while with the main activity and the main bimodal
the main model is going to be in charge
of all the UI logic that goes into main activities. For example processing
the touch events the logic behind what happened
here we don't have a business layer that we don't have
any like in use case type of classes but we
do have the Italian the it's going to be the title
repository in this case, because that all the
messages that you've seen on the screen they
come from the network and the database. So we have to leave the sources. So we have the local paper
source with the database here and the network as the
kind of remote source is there a reason
we're using coroutines in this specific context like
what would happen if we try to do this without it is
actually that's a very good question because if
we take a look at the code that we go here we
take a look at the code the starting code starts
without curtains so if we take a look for example, maybe a model we will see that
whenever we want a database it's doing something
without things and now we can explain a little
bit what it does but kind of the exercise of this
code that is converting all the asynchronous code that
we have here in the project to use coroutines and actually
it's now that you mentioned that if what we are doing here
updating tops what's going to do is that it's going
to increment a counter and it's going to
kind of simulate that something is happening
in the background. So background here if we
take a look it's actually a threat pull of two
threads and so like the way to execute something
in the background that you can use executor's
and that's basically this is a way that you can
create a threat to threats and basically here what we
are calling it a clean submit and we're putting out
runnable a block of code that is going to say, OK
run this in the background. So what are you going
to do it's going to slip it's going to block
the threat for one second. And then it's going to
update these stops which are life data are mutable life
data it's going to a database to be whatever and that's going
to be displayed on the screen. So that's actually
something that we are going to go in a second and
we're going to convert these to you to clothings and of
course this code is not using grouping's and this is going
to be like for using you you need to implement add some
dependencies to your project actually feels like there is
like also if you're currently using our server there is a here
like a library the cutting room things are that basically
it's an interaction between computers and you can
have a bridge between those two and you're going to have to
migrate everything at once OK, let's move on a little bit of
theory created by my Sean I also like a pretty good feeling
is very interested and one of the problems
that krotons tried to solve it's reducing
the needs of callbacks and here we are talking
about the callback pardon but I want to show this
in code and basically this is going to simplify
all that let me show you some code for that. So here is a title,
which is actually what's called whenever you tap
on the screen let me show that. So whenever you tap
on the screen says amam you click it's going
to update the taps whose code we've just
seen this one here and it's going to
refresh the title and refresh the title it's going
to kind of show the spinner and it's going to
call the repo layer and it's going to call
this method called refresh title with callbacks
and it's passing a callback why is it passing a callback
because the ripponlea is going to make an encore request, which is going to check the
database in the background Fred it is not going to execute
that code in the end if we were to execute the
network calling that in the way Fred the spinner won't spin
that's because the thread is blocked and the UI
is not responsive that's why we need
to move the execution to a different thread. So once that's clear
basically if we execute this so reverse
title gets executed spiner is going to be true we
just make a call to the repo and nothing else happens. So here these functions is going
to return because basically with the callback what we
are telling the repo say, OK reverse the
title and whenever you are done please call
me back with a callback call me back can
get it like that. And basically there are
two ways the things can go uncompleted means like
Yeah the title was referenced properly basically
spiner to force because the title is going to
be referenced in some other way. And if it there was an error
that was not put on the screen. So a couple of problems
with that as a problem with callbacks is that you need
indentation it's quite difficult to read what's going
on because you have a callback and then you have to implement
different methods depending on the path that the request
took but then like some of the problems with callbacks
are OK what if I want to make another asynchronous request
after this is a request I need another callback inside the
callback and then it is more difficult to read and I'm one
of the problems as well with callbacks if you take a look at
the implementation of refresh title it's actually it's
going to make that request and if it's successful it's going to update the database
is that this is happening in the background right so this
is Colleen as we were saying before bigram that submit and
it's going to do something but this callback whenever we
call here whenever everything goes well or there is
an error at the callback is going to be executed
on the background right but here we go back
to the numeral code we don't have any clue that
this code is being executed on the background and
that's for readability and for maintainability
of the project that's something really bad. And that's why here
in the live data we have to post value instead
of said the value of the value allows you to update the live
data from a different thread that is not the main thread. So there is no guarantee
that this code here is going to be executed
on the main thread and with Corinthian's we
can guarantee that OK I think that's fine this is
for example anaglyph request it's going to be synchronizer
it's going to be hearing the comment make an actual
request is going to block the call any current
advice when I start writing some great things Yeah I
guess one question I had is what exactly does it mean when
it says that request is going to block code what exactly
is that blocking Yeah it's going to block the thread. So for example, whenever you make an request it
might take some time to reach the server get that response
back the but of course it's going to take some time
to process the request and you need to parse the response
in some way I know that all the time where the next request
reaches the outer network at the internet that time that
your thread is going to be doing nothing it's going to be
blocked because it's waiting for the next request to come
back and if that's blocked means that no other code can
be executed in that threat but we've got to do is we
have something that instead of blocking it is going
to suspend execution and so whenever you
do hit you we are talking about suspend
that whenever you suspend the execution is going to
suspend but the thread is going to be free to execute
other things that may happen in thread. And GUID when the request
comes back then it resumes execution it saves
all the variables it saves everything that it needs
to do to resume execution after that request comes back
got it for this kind of case, what if I wanted to
use an async task is that something that's
valid should we still be using async tasks no easy task it
was a good solution very long time ago but it was deprecated
in 111 and the problem is in part because it was
really easy to leak in memory and actually it was
kind of attached to the lifecycle
of the BU layer. And here we could be
we can say, OK, we're going to see that we have we
can use different scopes to tie certain requests to a different
lifecycle in this case, for example, the
new model got it. Nice OK Yeah I'm excited to see
the lifecycle stuff OK let's try it I mean I think
it's 20 minutes, I haven't seen I haven't
shown any current code this is going pretty well
OK OK OK I understand, including scope I think
I'm going to skip this and I'm going to probably
talk through it later. But basically we are sharing
the model of database with some we said
before that this is doing something
about the threat let's convert this call
this specific code which is very simple to
kirkenes OK here we have kind of the solution but
let me do that Meanwhile I'm going to be talking
through what I do. OK maybe model. So we have this update database
that we want to replace and basically whenever you want
to execute something including actually is a private firm
I'm going to comment this out but you and I are going to agree
that the private firm it's OK and now we're
going to say, OK, I want to execute
this in a actually if we say like that
count was not accurate. So we could certainly do that. And I have the technical
and how can I do. How can I create a current
team from the demodulator we have something that
is called coroutines code and the new model comes with a
built in audience called code which is called beamlines code. And let me touch on that
later a little bit better with me for a second exactly
the background to me thinking I can create kind of the same
thing actually this code here the model of the launch is
creating a new coroutine and I got a team you can
think of it as some easy way like for example whenever
here we have a background that submits that we're
passing a runnable kind of can think of this
as in the same way you can think of accreting as
a runnable with super powers with super powers because we
will see that it is really easy to do things with the
background execution as well. So here we actually can
do exactly the same thing and we're going to see the
differences in a second OK so we have a friendship
and then say, hey don't do this because this
is going to look different. So I'm probably like I can do
the same so we are starting with exactly the
same goal and we are going to improve it OK so
what it's bunol scope so I was saying like every
character needs to live in a specific
scope and the great thing is the scope is the if we take
a look at this it doesn't matter to scope it's going to be the
entry point is the way you can create a grouping and basically
that with accreting the scope you can get track of all the
things that have been created with this specific scope. So here we are not
in accreting here we created accreting
one of the things here to take into account is
that the amount of the scope is configured with a
willingness to purchase domain and this is the main I'm going
to put that here it's better the main it's going to execute
something on the main thread. So basically launch
I say, OK, I want to execute this coding
on this particular domain but this is not what we were
doing here right here we were executing on
a different thread. So the way to create
a grouping that executes a different thread. So we have different
sponsors these mainly tell the group
where to run and we have one which is default
is a threat that is already configured in this and it
has a number of threats that you can use to run
things in the background. So basically here we
just created a grouping that is going to be executed
on a background threat so obviously if we do this
if we use if we execute this block of code mean. And if we as the
threat that's going to be pretty bad
because it's going to look at the main thread
here it's kind of OK but it's not OK
because obviously you shouldn't be looking
at any threat because otherwise the
threat becomes useless it's going to become there is
going to be used however there is a way to slip in this. And that's with the
delay function and delay if we take a look at it that's
just brain function that is going to kind of delay the
execution of this block of code for a second. And then it's going to
execute this bit so what does it mean that it has
to brain function here and actually you can
see the right call that means that this is
a suspend function as suspend function
means that the execution of this grouping
income to suspend and this is what it does so
whenever you execute this been on the background
threat it is going to wait for one second. But it is not going to
look at the threat threat though this was
blocking the threat but delay it's going to suspend
execution what that means is that while we are waiting
for one second order code can be executed on this Tread. And whenever that second passes
then this code will be executed this is not known when to
resume and suspend execution of a certain block
of code but something we can do as well
because here we can say, OK, I want to execute
this imane this cold here it is not going
to pass it is not going to block
the main driving I think it is going
to suspend execution so actually this is safe to
call from the main thread because this is going to spread
is going to block and so here and instead of
saying possible we can actually call value and
assign perhaps absolute value, we can assign you
directly because it's guaranteed that
this code is going to be executed upon
the main thread because we executed it here
something to keep in mind is that view model
Scoop by default is going to use this pattern
logmein so this is a little bit redundant if we call
this block of gold is going to be
executed on the matrix OK we created our
first cherubini any questions Karen Yeah I think
you already touched upon this a bit. But some of the live
chat was wondering how do they know the
behavior of the default dispatcher in that
launch function and I think you said it
was Yeah Yeah the default is better it's pretty confident
in encouraging so we have like I said here
you can see, there are four dispatchers available. So it is default
but it's basically for things that need to happen
in the background threat, then we have allele, which is specifically used
for intensive operations like for example
network or lisk and we have an unconfined which is
something that as a beginner you shouldn't worry about
it is not commonly used and not in production code
that much so default for CPU intensive tasks
mean for things that need to be executed
on the main thread or of things that
are not blocking and then allow for the rest and
actually like I mean you can go into the implementation
produces like a default escolar but in this case is
using like 64 threats and things like that. So you don't have to worry about
don't have to worry about that. That's like pretty
configured for you and ready to go to
be used nice I think there was another
question about what would be the right way to
call a suspend function on the main bread OK if you
want to call us suspend function from the main thread
that you create a thing with remodelers
code for example, you must go to the launch. And that will be executed and
that's basically how you create a curtain on the main thread
from the bimodal scope we will see later that also the
regulator has a different scope and so I was saying like the
recruiting scope here is quite important because imagine that
you are doing like a really long operation imagine
something that is very expensive and it's taking a lot of time
and it's going to take 10 minutes or whatever it is
obviously this of memory because if you are doing
something crazy and then here you are referencing something
else until all of this doesn't finish this runnable
or this is going to be memory the good thing about the predefined scope's
is that whenever the remote is going this
way, that whenever the value model goes away gets
destroyed and I'm clear this new model is going
to get destroyed meaning that all the characters that
is execute them they are going to cancel I'll just leave you
mother was like you can create your own copy if you want like
for example, we can call mysql if she goes through
a cooking school and basically the
curriculum is going to take the group in context
as you can see here and the context is basically
like a set of elements that is going to configure
the decorating and for example, one way
to configure it is say, OK, what is the default dispatchers
so numerous in this case is using these package with may
also have something like a job. And if we have time,
we will explain later I got the job is
basically this is mainly this is it's configured with a
supervisor job and this matters to me so every time that you
create using mysql or demands it will be executed by
default on the Main Street and then of course
then view model you have to be clear that you
want you can know when the view model is going to be
destroyed and basically what new models go
between under the hood and we can do with
my scope in fact, you can call my
corporate council to actually cancel
all the things that are executing at this
time and for example this one that is
taking the minutes it's going to be x is going
to be canceled because we will remove we cancel its scope. So this is a good way to not
leak memory and make sure that you wrap up and
clean up everything whenever the new model
in this case goes away. So why do you think so by
using the default scope. We don't have to specifically
call cancer ourselves when the moment is cleared that's
right bunol scope is doing that under the hood and that's why
it's an easy way to get started with curtains otherwise you
would have to create your own scope and clear it in all your
models if you use bimala scope that boilerplate goes away
because everything is done for you cool Thanks for
clarifying that OK so actually something worth mentioning is
that there are some questions and some confusion regarding
when do you create a school in which letter basically I
recommend creating a grading school whenever you want
to control the lifecycle of groupings and basically I
would create a Gradescope for the new model later
because I that's kind of attached
to the BU lifecycle and he knows when
the screen is going to go to the background moscoso
base configuration changes. So in under it you know
like the new model school it's a natural place to
start creating things but then if we go, for
example, to the ripple layer a ripple layer if it's doing
an operation that is linked to the screen as we are going
to do right now it doesn't need to create a critical school it
just exposes brain functions and we will see in a second
actually let's move into that and undo that I think I mean
not following the collapse that much to be honest. But we are roughly
here in section where we created
a accreting here I think we're going to talk
now about section number and we are going to basically
convert this refresh title into intercutting so basically
what we are doing basically it's I'm going to copy this
code a refreshed title I'm going to go ahead and copy that
into my understanding here and maybe model so basically
as we were saying glutens read sequentially we were saying
before that routines are going to remove the need for
callbacks and that's because in the
callback you're saying, OK whenever you
are ready whenever you finish your work then
execute the callback that I'm passing to you and that's
because the mechanism work in that way. But we do things
instead of calling a callback we can
suspend our execution until that work
finishes and that's what we are going to do right
now so refresh title ridgeley let me come in this
old refresh title here the previous implementation
is using callbacks but with thirteen's
actually executing this on the main thread we are
calling we are showing the spiner we are
calling the report and then in case there is an
error I want to show the snack bar. And finally whenever the Refresh
title function returns then we put this in a default
because we have finished loading the items that you can
see with croutons we here we will see later that
refreshed title it's going to be a
suspend function. So whenever you call
repo refresh cycle this block of code is
going to suspend execution until refreshed title
finishes so there is no need for callbacks because
the next line of code here next line will be called where
will repo finishes refreshing the title that's pretty neat
and that's why you can see all the complexity that we
have here with callbacks the complexity
goes away like you can read this function you
can read this kind of thing and it reads sequential
like everything has a sense. One thing gets executed after
the other OK I refreshed title how basically it's
complaining because we don't have a refresh title
but let's create it now so I'm going to create that
suspense function refreshed title and this one is not
breaking any parameters yet. So you can see I created
the suspense function. And now the clutter icon
appeared it means that this kind of thing can suspend
execution OK so suspend function that this was the
key word here basically we are telling the Kotlin compiler that
this code needs to be executed and that's just by simply having
the keyword there is function cannot be executed from
a regular function. For example, if we come here
we are hearing refreshed title from the New model here I'm
not in a courtroom and I cannot call regretable because he's
going to give me an error and say, hey such brain
function that needs to be called from
within occluding and that's basically
how we want to guarantee that these group and specific
functions run on occluding OK so let's go back here
we're pretty much going to do the same exercise that
we've been doing before we have the code here we are going
to convert it to accurately so basically I'm
not going to submit these runnable or this
work or this block of code into the background
threat I'm going to execute that code
inaccurately so basically of course now what happens
with the callback well, we don't need a callback
because basically this is going to return whenever
it finishes so because this is the kind of a
bizarre little bit harder to read because we
have pretty much assuming but basically instead of calling
uncompleted we don't do anything the function
is going to return the suspend function is going to
return because there is nothing else to do. And instead of calling
the callback with an error something we can do it
instead throw an exception and we can say, OK,
I want to throw here the type of refresh
error if I could then be able to replace the title
I'm pretty much the same here so that happens
through the exception. So you can see it's
actually reads pretty well. So I'm going to try
to do something here. I'm going to make this request
that this synchronize and we will see a leader
how to avoid this. And if it's successful
I'm going to insert the title in the database. And if not I'm going to throw an
exception that the grouping is going to catch we will see later
that actually this first title has a three page show here
it will come to this OK if I don't do anything if I don't
got anything here this has been the function is going to be
executed on the same thread where the Corinthians has
been launched and in this case because this was launched in
these pages the main discussion is going to go to the main UI
thread 100 and this is going to block the thread because
this is a or something we can do to move the execution to a
different thread is using a function including
what is called with context and with context
basically what we are doing is saying, OK,
this piece of code that I'm going to
tell you execute it in a different context. So something we
can do is that this matters because we are doing
have request I can certainly have that in your dispatcher
so execute this block of code that I'm putting you in
the other thread and now and this is safe to be
called from the main thread. So this is called from the
front whenever it comes here I'm going to swap the
execution of this thing to be done in the area. So now all of this is
going to be in the abstract if we take a look at
with context what it does is that these are
suspend function, meaning that is going
to suspend execution and actually it is going
to the grouping that caused this function it is going
to wait for this block of code to finish before returning
so something like we can do instead like here I
want it to be clearer, and it doesn't read very well
but something I can do it's doing that reverse
title and basically I can call with context
inside this thing. So here are these
executes on the calling this pattern
actually this will be this part of the group in
this part of the block of code will execute on the
main thread and now I'm swapping to the thread. And all of this is
going to be executed on I use it on a tripod that is
configured for that obviously still this is a blocking code
it will block the other threat but it won't block them minimize
and that is what we care about 200 cool any question
Carol Yeah I think Maya had a question about what's the
difference between blocking and suspension because a lot of
times you're saying something has been blocked and then
you're like hey we're going to create a suspend function. So you kind of give us more
tomorrow that Trump so here as I was saying with context
is going to suspend execution and I was saying like after
OK this is a pretty long line of code let me see if I can do
this OK so with context here this is going to suspend
execution until all of that in here finishes meaning that
now we scumbag's only back here like this is going to execute
on the goal in this particular well as well right so what it
means with suspense is that you're executing on the
main thread the is executed on the main thread now I come
here and it's going to suspend execution until all of that finishes
what that means is that whenever
it comes here it is going to be on the
main thread as well. But the current
execution suspended while all this was
happening under your thread. And because it
suspended it means that now the only threat the
main thread was the killing dispatcher is free
to do other work so Meanwhile they
are your request is happening the way Fred kind
of still being the spinner that we have. And so basically
suspending means that hey I'm going to
park this block of code that I'm executing
and going to put it in a specific bucket
full for later and I'm going to be executing
other things that are being dispatched to my thread. And whenever the actual
finishes whenever like this piece of
code here finishes, then I'm going to
take that routine back and I'm going to
continue the execution if we see like the
blocking call if this was a blocking call
that wouldn't happen. So if this is blocking the UI
the threat wouldn't be able to do anything else it will be
blocked the spinner won't be able to spin because the thread
is busy waiting for the other request to come back versus
with good business bad behavior it's free to do whatever they
want it wants to do and then it will go back to that
execution that that was left in the middle and then carry on
executing and what it's called it is going to resume executing
so resume executing on the main thread got it that makes a
lot more sense than shib had a follow up question is a
guarantee that the same thread will resume the execution after he got expelled
suspended or are we not sure about that right so the main
thread is dispatcher's logmein is configured with
one threat so here because we were saying that
default has 64 threats if we do this pattern
that I you're here and and then we deal
with this context again with these pictures
and you obviously this is executed executed
on mean it is not guaranteed that they could
get executed this
So he says if we mark room dao method with suspend or retrofit one then we can call if from main coroutine dispatcher and it will switch to some thread. I wonder about 2 questions: