Warm greetings to everyone.
Everyone please welcome welcome to the second online wait up of BLR droid I hope everyone is safe and enjoying. Working from home we have two tops two days 45 minutes each and I hope you like them.
Whoever is joining for us for the first time. Like well not join one for last Peter the format is basically.
We'll have two talks one by one Q&A will happen after the talks and any questions any questions: Which you want to ask you can ask on comments after the talk has finished.
So okay you all right so we are gonna start our talk with sobriety so let's get started:
Hi sobriety and I how are you let me just introduce Vizio TVs Android developer who was fed small case and he is no no I talk. About linked I assume everyone knows Android links so I'm gonna add your screen now so put your teeth okay so yeah you!
Can start hi everyone my name is Pedro Jody and I didn't mention I'm a mobile? Developer etymologies today I'll be talking about building a better code base with link I'll be going through what the link is why you should actually.
Care about it a couple of examples of how we use custom link rules for the ticket of Android. App how you can catch the link rules and how you should go about adopting custom. Link rules or enabling League in a project so let's start.
Off by looking at what link is I'm sure most of us would! Have team of up with link at some point it'll be the global to static analysis?
Tool so our static analysis tool runs takes on your poor face without.
Actually running it so it won't look for things like compliation? Intervals rather it would look for common antipatterns performance issues security issues and things like that it's completely open: Source and it's developed as a part of a OSP and an open source project all the rules that you get enabled:
By default on Android studio whatever you see related to edit text excuse all of that is open source normally. We see Lin show up for Java and XML files Berlin. Can work across Java Kotlin great pro-gard even by the defense it can be used outside of Android as well initially it was meant just for Android but.
When Cortland came in and became big the team at brain started writing some more link checks.
And they realized it could be useful for non Android? Developers as well so if you're making something like a cater server you can make use of certainly extend the tooling system is built in such: A way that in addition to using the people tools you can write your own custom rules and they use the same tooling:
As the one you're in PC so if you need some reference! There are already about I think 300 plus P built-in rules that you can look at and one advantages is it can be done both.
From Android studio as well as from a CLI so if you're a person who doesn't like building! Inside Android studio for many reasons you can run link from a command line and this also. Comes with the added benefit that you can add it to your CI pipeline so you can make.
Sure that all your bills actually pass live ok so we will. Take a look at how we visually see a lot of examples of linked and keep?
In mind that these are not random examples these are categorized examples and we will be looking. At the different categories going forward so the first one is I think the most. Commonly warning that we have seen is hard-coded text if you.
Look at the tool did you will notice that it shows where your warning is in the text view it gives us small description of your. Links check and also give you an action in this case extractive in the spring will search for different. File and the category for this would be internationalization so that you can localize your strings to different languages the second example though.
This link from a different perspective later on the third category would be performance so if you're working.
With custom views it's highly recommended that you do not create objects inside your on draw especially heavy objects so if you look. At this links check web view is a custom view and inside the armor I am creating.
The pinned now this is not suggested at all since your paint object will be created?
Every time you're on draw this world and on draw is quite very often the third would: Be accessibility related even though a lot of us actually relax this ability by making your apps it's still an important aspect and that's the reason there.
Are a couple of pre-built accessibility checks so in this case if you creating a custom view and you override. On touch event for accessibility purposes you know also supposed to over it performed it now coming to why you should consider an evening.
In or writing custom link rules and why you should be listening. To the stop the first is you can have an opinionated code base so as developers all of us tend to get opinionated about the.
Kind of code we write and as you work in teams sometimes teams. Have opinions on how the code they. Should be so if your opinions of the code base can be defined in a structured manner you can make a little check.
Out of it so that whenever you write code you can make sure that you follow that part of the be needy code base! This also come with an advantage that can be derived from the same opinion with good bass is you can have. Simpler code reviews so normally for such code bases whenever you review the code the first things.
You would look for is if they adhere to the common guidelines for this: Goldfish and this can get tedious to do with every code review because you would by default.
Check for those things now if you have the lane rules that check. For this thing before it went for a code.
Review it would fail in the CI pipeline and the developer. Who push the commit would have to fix it this also gives. A more positive outlook to the will requests:
Because you go to review it knowing that the common issues won't be there and that you should look at performance! Test coverage and other things of the codebase I mean. Of the pull request and the third would be appearance to a style guide a lot of big products and apps have a style?
Tag applied across the entire app which also reflects on the websites and other platforms. So it could be how your buttons are supposed to look what font and what takes the pages you're supposed to use for. Different cases and these are things that are essential once you have this.
Dialed enforced now if someone new comes into your code base obviously as a part of their onboarding. You would tell them about all this guidelines and in detail. About the style guide but even then the person might miss a few things and this necessarily isn't.
Comes open screen to new developers even developers who have been in the team for a while some might sometimes: Miss out on the guidelines so if you're working on a certain performance aspect or you are.
Knee-deep in a very nasty bug you might just funk it or accidentally use the regular widget. Instead of the style get fidgety and which is quite understandable but if you have. Lane rules to enforce that you do not use the common widgets for example instead of using a button:
You use something like ticket a button which is a part of the style guide lint will throw: You an error and tell you that you are not supposed to use this this. Is the guideline and this is the component is supposed to use instead of next year this again!
Make sure that your code base is very standardized in terms of views and everything: And also you don't have to look for these things in a. Code review again we will be taking a look at two such.
Style great examples that we use on the ticket tip to explore how to write such rules okay to set up custom. Lane for your project you would have to create a new module you can name this module whatever you want in my case it's.
Name is link but any other name works and it's okay even if you are not following! A multi modular project you can just:
Create a new model for later on in so fine in the link modules dependencies you have to add or two dependencies. From length that is a Lindy API and link checks these are the same liabilities!
That even the AOSP link jects use so it's very standardized then you have this thing called.
An issue registry an issue registry is technically a register of all the issues your link looks. For this is the standard structure of ancient industry but take a look at the overhead.
Valve issues property what this property does is return a list of references to all your issues so that link? Knows what to look for so this:
Edge is free connect linked to your custom. Rules since you don't have you don't have any custom rules written yet this is an MD list after. You have created this registry you have to link the Center Street to your model so you have to add this jar block?
To your link modules will not reveal the reason is a jump our block here is whenever your?
App is compiled this creates a jar out!
Of your link wonderful injects an Android. Uses that jar to check all of the link tools so if you're writing a library that has such rules.
And will ship that library anyone including! The library will also get a job with all the custom checks for the library similar example for this is timber so if you have used timber. By Jay quadrant you will notice that whenever you when we say including!
Timbering a project and then using android song in class for example not Verilog.
Dot T or lock dot e you will get a link warning. Telling you that he already has included temple so it might just be better to use temperance the flock once your bad with this. Jar dependency you have to put your.
Apps window cradle and link your link module to your app model and the way you do it is using. This link checks you can see that the tooling is properly built out because there are separate?
Tags and methods to integrate link into booties okay before you start writing custom controls there? Are three common things that we should know about first.
Is the scope then its category and then comes in severity so first we take a look at school the way you tell linked to check. For issues on certain files is by using: This code it would be very expensive if your checks on every type.
Of file that is in your code base and that would be a performance issue as well because you can have a lot of such? Files so by using scope you narrow down the number. Of files on which the link eggs need.
To be applied on so you have a Java file scope Gradle scope manifest ProGuard resource file these are the some of the scoops.
There are other scopes as well which can be used to combine those. Goals so if you want something that runs on - sir - particular scopes there might be a third scope defining.
The Pyland which is a combination of those two and since the lid API was made when a quater.
Link really wasn't part of the Android ecosystem there is still only a Java file scope but this also applies on coding files. As well the way this works is linked directly doesn't apply.
On Java files it rather works on a super-tight of both length. And Java which is you AST universal abstract syntax tree so the abstract syntax remains similar for Java and godly and that's.
The reason the jig's that you write for Java files also apply on godly: Files the second would be the severity. What is the severity of the so what is the severity.
Of none one second I think a little bit of it what is the severity of the.
Error a warning that the issue link finds. It could be informational warning error and fatal informational is when you want to give a certain information to the developer and not really cause. An error warning this could be s of your opinionated codebase example a warning could be something that's highly recommended.
For the user but it shouldn't cause him to fail error is when he is supposed. To fit for that issue and the last type is fatal fatal has to be use very carefully because if you have an issue that!
Is fatal and you're trying to build an AP game even that would say Satan is like.
The most severe which can be destructive to the poor base I mean it should. Be used for issues which could be disrespect if you've got this the third one is category now again here I'm saying four categories.
By there are many more such categories the four categories again from the examples? We've seen before weather security performance internationalization and accessibility there are many more but I took these four because I could throw examples of them from.
The people and you might see that I've. Written I 18 M so even I recently realized that.
I'm 18 n stands for internationalization because ray 18 characters.
Between I n n similarly faxes ability there are 11 characters.
Between a and Y so it's a level? Similarly localization would be held in n ok I had mentioned that we would be looking at two examples. From our app and see how we wrote custom.
Link rules for those so both examples are related to style guidance. The first language will be looking to estates you so should take a look at the image you will see that! There are two different types mentioned one is h1 display mobile h2 display mobile and.
There are many more like h3 they could be captioned! There are many such modes many such types and each type has a set of properties. That will be applied for that type initially we even used in custom use for these text views and different attributes.
But later on we decided to move to styles as they were much more flexible so what our limbs checks! Need to do in this case is if someone. Is creating a text view they have to add a style.
To it and this would be an error because if they don't apply our study to the text view we can have design distances in there. And since it's a highly enforced design. System we need the site to be there so let's let's take a look at the custom?
Rule structure at the core of the structure you have something called. An issue this issue is the one that is connected. To your issue registry so this becomes.
A core part this is the way you create an issue I will be going step by step to each of the parameters: The first parameter is your issue ID this is the unique identifier. For your issue and if ever need to do anything with this issue you'll be using this ID for example if you want to disable this.
Particular limit role you would be referring to this! ID email in two options the second is a short description of your link it's the first thing that shows up in your.
ID the third would be a longer description in which you can add more details as to why this is an error you could? Add links to your style guide and such things. If you come to the fourth parameter here comes the categories.
We have mentioned since this doesn't fall into any of those? Previous sections for categories we are using the correct category.
To define that is being correct to use text you to that style the next parameter is a priority. Parameter this you can skip I personally couldn't find any difference when changing the values. But if anyone knows anything about it I would love to know next:
Comes the severity as we have mentioned the severity could be informational warning error. Or faded in our case we wanted to be in error because then we speak quickly! Want styles to be applied excuse and then comes.
The implementation part you have the issue but the issue also needs to link to your implementation of the then! You mentioned the class so it's just not the class name its master Java because it needs the class this is a reference to area!
Implementation lives and also the scope so in this case the scope is resource file scope. Now you might have one concern at this point is that we would be defining text views. In XML only in layers but resources have a lot of different kinds of XML files so this might needlessly.
Run on a lot of other files as well so we will be fixing!
This shortly in the next step in terms of scoping. There is a sometimes you might not get very fine scope or rather you'll get jaded scoops so in the implementation. Is the fine unit okay since this is linked dual for an XML file our class needs to extend the resource.
XML detector since this is looking at resource examples: Similar teacher looking at Java code you could have a Java scanner? You have different like you waste a scanner if you want to do or more about the structural issues of cotton and Java files a source!
Code scanner to go to the entire source code it depends upon your usage: I mean your context of where are you using this lecture in this case resource XML adapter works. Fine the first thing that you override is get applicable elements this specifies which particular elements within.
Your link rule run on and you might have one lyndie issue that can demand multiple types of elements that's how it takes. A collection as a return it but in our case you want.
It to apply or you could excuse so if possible list of textures now! As a coding practice it's a bad practice to use hard-coded strings so what you should be doing is using a constant. Fortunately the Lynde library has a huge collection of constants which you can use for which we use from if you are using any of if you're writing.
A rule for any of the androids widgets which.
Are pre-built it's almost certain that you will have a constant: Correspond to that in the SDK constants file the reason it's really good to use constant because I personally misspelled a certain.
Element once and I spend a lot of time? Figuring out what went wrong the next method that you need overhead is obliged to and this:
Gives you a folder type now remember that I mentioned. Our issue was not verified things we were looking at resource files this overhead method is where we specified that inside resources. We want to look at only layouts and what happens:
When Android sorry on link finds a certain element which is a textview in this case. In any socially out fine what does it have to do here comes the logic of checking things so. In this example we get access to a context and an element the element.
Here is our text you so we check if the element has an attribute called sign again we are. Using a constant here instead of hard coding style element has a element doesn't have.
That good style then we will put that link issue and when it importing the first parameter is issue and: This is the same issue you had written in the beginning.
The element is the widget for any file therefore anything that your rule should show for natural:
Element and also the location where it needs to so that you get some context of that location and the. Next one is a string message you can give this anything.
You want so you've completed the custom rule now you need to add your.
Issue to the registry so that Lynne can pick it up in this case since.
You have only one issue you get an act you get access to the issue and add. It to the list now remember that I mentioned get applicable elements was an important overhead? Method we will take a look at an example of where you get applicable elements:
Link warning less of you so that's the reason always remember to add proper constraints?
For all the lipsticks you write otherwise you'll just keep getting random. Link checks which won't really make sense coming to the second example: In our app we have a custom implementation of a snack we don't be used for example the material libraries.
Stack back so we needed a link check this time in Java code or Portland good if someone! Uses snap but material library snackbar we tell them that but do not use that use a custom.
Component to align the styloid so let's take a look?
At how we would implement that the issue structure is again.
Similar the only difference you will see is towards the end. In the implementation my scope is Java file scope its earlier we will using a resource cook this time we are using a Java.
File scope also remember that Java file scope applies on portal in science.
As well now looking at the structure? Of the link tool this will have a lot of similarities. Compared to the previous rule in this case we are not extending.
From XML or scanner resource XML scanner but rather we are using the detector interface. And the source code scanner these give us the necessary contacts we need to implement. Our rules now in this case since we are working.
With Java files we would look at classes the kind of methods that the calling and the parameters of those.
Methods and this lead role is kind of inspired by whatever.
Rights but the timbers Lindell are much more complicated because they provide fixes whenever there's a linked error in our case we don't provide. Fixes so get applicable method means we'll look for the make function. Invocation so normally if you're creating a snack bar it would be snack bar dot make so you're looking.
For this make method name but like you mentioned in the previous example we also have to add a constraint. Of the file on whose instance snake is mingled so Donna. The other overhead method that we use this visit method called so whenever the method.
Function is invoked we would get this callback now inside this we get access to the context and other parameters which. We won't be using so I mean we would be using the method parameter to get to know the method mean so we have to check if.
That method is actually a member of the material sniper class so that's when we use the context to get the evaluator and the evaluator.
Checks if this method is actually a member of the material sniper class now given this constraint if there are make.
Methods in different classes it won't apply on them so we want come across such a bug. And if this condition is met then we just report. The you to sit similar to how we did for textview now that we have seen two examples of the student rules.
Or the next concern comes is testing so ideally: When we write such good things in our code base we want tests to make sure that they are done properly: And we don't break them at certain point when making.
Changes so testing with link is actually pretty convenient you write.
Normal J unit tests so they're extremely fast and read gives you a link test libraries: Library which provides certainty a sense to make your testing comparatively easy and seems you're not a pollinator and the third would. Be Android studio and IntelliJ have syntax highlighting for a syntax.
Highlighting as well as index checking for the code you write in your. Linked rules let's take a look at one such example this is a test file in check don't look at the implementation completely focus! On the text view partners you can see that.
My idea is informing me of a certain error and this looks like a syntax error if you look at the second! Line of text view you will notice that I have enclosed the goods after match parent.
There is more put and as expected the code or the ID is giving. Us a syntax warning as well as highlighting the text.
View widget as well as the namespaces. So this makes it very easy to have a glance of what are the things being included:
In the test so before you start! Right in the test you have to add the dependency for! Your link test like theory this will be included in your link module okay we will be looking at two cases one case where.
After running link you're not supposed to get an atom and the second case we're running limbs will. Give us an error and we will test that error so the first one is to check for little intervals. I mean for norland error so you start by adding the link method god this starts the DSL next you start calling a file.
Block files now this files block lets you define the kind of files you want to run tests: On it could be Java files quarreling. Riddle scripts XML files a lot of such things it's similar in terms of scope but it's broader.
Than that I mean you have more choices since we want to test. An XML snippet which has to be in the layout resources so we create this kind of a mock or XML file where.
We mentioned that the path is in resource:
Layout and it is in a file or! Layout XML and then we mentioned the code snippet on which we want to run away if you see there is a style attribute! On this text view and there should not be any link that is what this snippet also note that my text.
Tube is indented to certain extent you have to be very.
Careful while adding indentation while writing your tests because the result of the test will vary depending. On your indentation link will ideally want.
To pinpoint the location where the error occurred which would include the column number. As a row number so if indentation changes technically.
The best also changes but in this. Case since we're not expecting email intervals any kind of invitation works for this particular. Case once you have defined your XML file you click.
The run block this runs link on the particular file a set of files that you provided now after running it what? Do we expect we expect that this should not be any link error we call the method xsplit expect clean this is a test.
That will pass since there are no like we are sure that there won't be any lint issues. Because we can see that the style has been added here the next example would be an error case where lint would throw another.
This test remains very similar to the bemis one the only difference is I have removed the indentation to make the decimal and this test.
Does not have a style attribute so you proceed to running that. Running lint on that particular XML file here we expect only one error account because we just have missed: Out on the style attribute so our expected.
Error count will be 1 now in case you and warning you would keep expected warning count as one.
You can even mix them both in case you expect. To get one warning and one error you will get the same so you can expect which so you can write expect their account? One expect one account one now we have just checked for the count.
Of errors but we also need to check if the output of the error is what we expect. In this case in the expect block we run the output that we expect from Lind at first mention the file name. The line number the description of the lint a pointer to the location where?
The lint error occurred and the number of errors a number of ones now? This might be very complicated to write so if you are sure that your link. Check works properly you can run it on a few tests file!
A few mock files that you write that you can create and then what you can do is call an empty. Test pure with just an empty screen run the link you will get an error you will get your destined sale and it will? Tell you that there is a mismatch you can look at the actual output comes pair it with your name if you see that!
It's a proper output you can place that in expect.
Block this will make sure that future changes. To this link duel won't break it and since you can see that there is a pointer to the exact location. Of the error that's the reason in condition was very important if you're planning on integrating.
Linked with your code base first thing is do incremental fixes do not try to tackle all the issues at one?
Go you will end up with a lot of such problems instead to use something like. A baseline so a baseline is a. Way of adding all your existing link issues.
To a file so that it filters out the same issues from future. Bills so in a way you tell. Link that in a way you tell in to ignore what the real existing.
Issues are and going forward it should throw errors or whatever issues come the way you do it is add the link. Options block in your apps bill got middle and add a baseline fund you don't have to create the file link.
Will create you create it the first time you run it so he said run link debug I mean easily run lint.
On my debug variant I got one error for my project. You can see that turn lint wrote an XML and HTML report first and then it also wrote! Those who might be a sly file then the file name.
Is the same as what I had mentioned if I run the same checks? Again this time it will be successful but it will mention that it did find one error which is filtered. By the baseline example if you open up the baseline file you can see that my issue.
Was registered in an activity and histamines file which i have created. Earlier it tells the issue and also the line and column number on which it occurred in the last consideration which. Many people have ever integrating link is performance and it's a pretty valid.
Concern looking at link there are two main categories of linkage you can think of one is a single.
Pass and one is a multi pass so a single. Pass example will be missing attribute like in our case the text for example which can happen in one parts.
And since it's only one pass it's fast and these are usually enabling IDs so the hard code is trained with?
The accessibility issues these can be found in one pass and so then enable by default in your ID by Ruby the second! Would be multi pass an example would be unused. Resources you might have noticed that the ID doesn't.
Warn you about unused resources by default it's only when you run a custom task or run it while adding a git: Commit that you get to know what I use resources because this is multi pass and it's slower and they are disabled by default in IDE normally?
You would want to add these to UCI because of few seconds more on it see I might be funny.
But lag while coming if a developer faces lag when writing. Boring is ID that really is in productive and that's. Mostly it about length if you have any questions I mean we have a Q&A session now as well or you could.
Ask me on Twitter at that's my Twitter handle Thanks sobriety's. So yeah if you have any questions please. Add them in the comments we'll take five questions at max at this time you so okay we have a question!
Let me just highlight it so Bridget.
I have been tried using linked as a plugin considering the ID support as well as the beetle. I mean so my line option has worked. Late so I haven't tried using this okay actually people have been asking for a sample project.
Way if you could showcase so I think this is the question regarding that only yeah I'll be sharing or the link with! The slides as well as the project okay so then we'll conclude this session Thanks.
Ability for joining and giving this session on links yep okay so we are now going to move to our next session let me just act akshay to the? Stream I am sure you are new so yeah now we have our second section with akshay which is regarding. Content flow a chair joined us all the way from Berlin in a different time zone he versus Android engineer!
Club and he is also a Google developer expert for Android I'll say over to you thank you for such a warm introduction? Let me share my screen are you able. To see the screen yeah I've added it to the stream yes go ahead action okay perfect um hey everyone it's super exciting to see people from India.
And so many familiar faces and even some people joining from other parts of the world I hope everyone.
Is coming up with creative ideas violet home and staying: Safe so yeah welcome and thank you for joining. I'm excited yeah I'm based in Berlin Germany originally I'm from Pune India so I over here I work as an Android engineer at clue!
Which is a female health company I'm also an Google developer expert for Android and today we are going:
To talk about something which many people are excited about that is scotland's. Flow so the goal of this this talk is to tell you why Kotlin flow was designed some basics. Sure what makes flow special how you can migrate to Cottman flow how to a direct flow on android and most important testing.
So before we go into kirtland flow is let's rewind a little bit and look at what Kotlin gave! Us that is co-routines so they simplify so what accordions they basically simplified a synchronous programming in general and especially. On Android so let's let's look at let's take an example of an synchronous function called a show user which?
Internally loads the user from the database: So when this function calls load user it blocks the current thread and waits till the user is loaded from the database this.
Blocking is bad because at this moment the whole. UI is frozen making the user unhappy which you would definitely.
Not want and once the data is loaded from the database the render function is called which!
Like renders the user data on the UI so there are like multiple ways to yeah yeah so there are like multiple ways to tackle this!
So let's look at how we can like tackle this problem using co-routines so let's. Start by taking the original as original synchronous function again show user and so first we what we will do is just.
Mark the the show user function with the suspend keyword.
Of course we will need to mark the the load user function suspend. Too because since we also want that function.
To run on the background thread but there is a problem. The render function needs to be called from: UI thread since it's touching the view hierarchy so we can in that case?
We can just use the with context! Function which allows us to switch the thread inside the suspending function so it will switch from background thread to UI thread and the render.
Function will be called in the UI thread and that's. Pretty much it that's pretty much it how you can convert a synchronous. Function into a synchronous using co-routines so let's look at how!
It will work internally so we start by calling the xu user function since it marked.
A suspend it will automatically switch to the background.
Thread or the thread which you specified while launching the pour routine: And then their user will be loaded from the. Database on this different thread while the main thread:
Continues to go ahead without waiting for anything. That is it is not freezing or blocking the user experience.
And and when it will and it will switch back to main thread.
Because of the with context function and when the data is loaded and then it will call the render function. On the main thread and basically display.
The data okay so one key thing to remember the suspend function can only be called from another suspend. Function or from a co-routine scope so so let's look at what Coradin. Scope is co-routine scope represents the scope of the core routines.
So each core routine needs to needs the scope to run in and the one so scope is basically more or less associated with the life. Cycle so when this scope is destroyed all the running jobs inside the.
Scope will will stop will be stopped: Or canceled so this cop is generally associated to life cycle like I said before for simplicity.
For an for instance on Android each activity has a life cycle so accurate in scope so the one of the KTX library provides: The life cycle scope so very where you can like just launch. Go routines and they will be destroyed when the activity is destroyed so let's look an example to understand this better.
For example in order to call our show user suspend function from a normal function we would. Need a core routine scope as we saw before so and like I already said like on Android: These cops are already implemented for us for convenience like the lifecycle scope which is part of the lifecycle KTX library.
From jetpack component it is provided to use co-routine function in activity or fragment! And so it's a co-routine scope which is tied to the life cycle of activity or fragment so this provides the magic! Of automatically clearing or cancelling all the jobs running in the specified scope so when the activity.
Or fragment is destroyed it's pretty much similar.
To how you would do it in rx where you manage a subscription and then unsubscribe like clear all the subscription. In destroy or something so this is done automatically using scopes in co-routine world so the launch scope the launch.
Function is used to start the core routine: And it will immediately start the core routine that means the core routines.
Are hot in nature and this is also one of the reason why Co routines are not like one-on-one replacement for reactive streams so basically. A core routine scope is kind of a subscription management system associated to life cycle so this concept is called. A structured concurrency and this is what makes Kotlin co-routines:
So powerful and also helps developers prevent deleting the job or the subscription which they were they they were supposed to cancel. So let's compare them to then come to the important question.