It's crazy how much has changed in Android development in less than 4 years. It's like I learn something, and by the time I've mastered it something new is made to replace what I've just mastered. 🤯
The goal is basically set at 4:26 but at the end of the video it feels like(as always) we are back to square one. On the hindsight making anything comprehensive and simple with fragment + activity with their lifecycles is incredibly complex. Throw in a service(Which connects asynchronously and has its own foreground limitations) that needs to be connected and you have to throw everything out of the window.
Sorry but who are these developers you guys are supposedly talking to? How many completely different async solutions are there now for Android? Like 30? Do all these developers constantly want to learn new ways to perform async tasks?
I don't get how Coroutines are presented as an "easy" solution.. They are very hard instead to use properly. I'm trying get it but it's far from easy.. Am I the only one?
@@_AddSense_ I learned Rx1, then Rx2...not even finished the project I worked on & everybody started pushing coroutines and kt then I switched to backend so I don't have to relearn everything every couple of months. I also pushed hard at first for kotlin then I discovered I hate it because I was never getting NPE in java either but with KT it keeps bothering you with nonsense ! ? ... for now backend is quite nice and stable
so many methods and so many scopes. It feels like patch work rather than a complete solution to handling thread calls and orientation changes. Specially in case of fragment. I am sure in future a lot more stuff will come to fix what is done right now. IMHO fragments itself should be re-written. For a beginner this is a very steep learning curve.
Wow! This session was just... perfect! Crazy how much easier and clearer this is compared to the workarounds devs had to do before, really shows how much we can improve tech even now. Really well explained and complete. Would be great if videos like these showing how to use a new feature from the ground up and relating it to other modern libraries were more common. Good work
About 30:00 , I don't understand how this works. It runs this peace of code on the UI thread, on start, right? So how come it waits for "note" variable to be fetched? Does it also re-load the data this way, each time it gets changed, or does it load it just once?
I don't event know what is better: write some boilerplate code but know what is going on, or learn a lot of new abstractions which you do not fully understand
At around 28:56 should this do the job also: suspend fun loadNote(): Note = viewModelScope.async { repository.loadNote() } I don't see the point on this CompletableDeferred. If it should be loaded only once you could use the lazy delegate. Why is CompletableDeffered needed?
I think the video's code on that slide won't compile (can't check now) and I think the viewModelScope {...} call was meant to be put in an init {...} block. The difference with your code is that your code would only start executing when loadNote() is called. This means that the repository.loadNote() call is started later and therefore could complete later too. However, this doesn't answer the difference between CompletableDeferred and just Deferred. A big difference is how they are built: Deferred is built using async {...} and CompletableDeferred through its constructor. The latter allows you to set its value (through the complete(...) function) from another place, which can be convenient if that place does more than just fetching one value asynchronously. Just using async {...} means you start one coroutine to get one value asynchronously as a Deferred. So in other words: it's the same, but CompletableDeferred used like on this slide is more flexible. So the same, but different would have been: class MyViewModel : ViewModel() { val deferredNote = viewModelScope.async { repository.loadNote() } fun loadNote() = deferredNote.await() }
I have used viewModelScope since it released but now after upgrade dependence version of lifecycle to 2.2.0-alpha01, I can't see lifecycleScope or liveData block??? Please help me to try it.
I found it in the mvnrepository. implementation "androidx.lifecycle:lifecycle-livedata-core-ktx:2.2.0-alpha01" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha01" implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01"
With more focus on Rx in general, Google should show why a reactive paradigm is the way to go. RxJava is a solution for this, coroutines with Flow will also provide a way to achieve it. But this is my issue with comparing RxJava and Coroutines currently. They are not comparable.
I think Google's problem is that Flows neither are stable nor have they been used a lot, so they have to come up with something in the meantime. RxJava is the logical step in between, because it's popular, flexible and powerful. The differences with Kotlin coroutines of today are big, though, so that's precisely why this talk just ignores Rx.
Isn't the statement "Kotlin calls loadUser just like a normal function" sort of inaccurate? Wouldn't you need to use either launch or async, for instance? So when the loadUser suspend function is called, the first thing that gets "suspended", in the flow of things, would be that wrapping coroutine, right?
android development would soon require to be only attempted by stuntmen and Phds. Phds who possibly had two or three Masters in various fields of maths science and computations
Well, I guess you don't have to follow any of the principles or use the tools available. But it in the end, it's about making a high-quality application. These tools seem complex, but they actually reduce the complexity of an app, so one has to choose either implementing a "complex" architecture from the start, or maintain an app that because complex after growth.
Hi Team, I hope you are doing great. I want to clarify one doubt regarding Kotlin Coroutines. How can I delay the execution of the next line or next block of code in my app until the response of my ongoing API comes? Thanks in Advance !!!
Looking at the actual code of the LifecycleCoroutineScope, I don't think it works the way they claim. Specifically, I don't see any code that would cause coroutines started with 'launchWhenStarted' to suspend when the state is < STARTED. The only thing LifecycleCoroutineScope seems to actually do is cancel when the lifecycle owner is DESTROYED. I'm wondering how much of this talk is actually useable...
@@DappOllone well, that's probably because onCreate is always (I think) followed by onStart, so, in reality, the only state that would prevent fragment transactions is onDestroy
10:23 : transforming to another representation from stack to whatever is used for supsendables and then back when resuming, and copying stuff sounds a bit comp intensive, I don't see why we couldn't build separate substacks for the suspendables in the main stack and switching into them and back when necessary. no copying and transforming involved. or am I dumb and threads couldn't manage that and point to other substacks like that temporarily?
Because that way you wouldn't be able to access local variables from that stack. That's why lambdas in java copy local variables and not referencing them directly. Because of that you can only use final variables in java. In Kotlin, because you just put the coroutine stack back you can treat it as a single stack which not only simplifies things greatly for you but for the cpu too.
Things are like getting out of hand soon. It is more and more costly to understand and master Android app development. Even the Android software engineer at Google has hard time to explain the things in easy to understand way.
I had tried these "new" coroutines a while ago... hard to grasp... The first iteration of this was much simpler.... I understand what they want to do, but honestly..... I think they should all be taken away from the development of any new feature for a couple of years, there really is no point now. And just let them fix their own mess and try to explain all of it as well. I don't see any of these people writing books, writing interesting blogs..... It just seems that software development is getting more and more 'magical' in order to fulfil some unknown need somewhere..... and moving towards tougher and tougher to grasp and to implement and to debug paradigms.... with little to no added value for the end result, which should be a humble app
to retrieve data from network and update the UI it's a such common problem that I would expect to have a easy way to solve it, considering common use cases like rotation or user switching apps, but apparently it always will be a complicated problem
1. CoroutineWorker - ok, I had to make Woker implement CoroutineScope before. +1 2. Retrofit - there is Adapter by Jack 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' +0 3. Room - ok, previously there was suspended fun in the Repo for this purpose. +0 4. LiveData with Coroutines - LiveData should be simple as F. -1 5. viewModelScope - Previously had to implement CoroutineScope. +1 6. lifecycleScope, when started - Good for Animations, Transitions, etc... +1 7. coroutines-test - Best part, trick with immediate delay is awesome! +3 8. Part where dude tried to get data in onCreate() - Uncle Bob would destroy you! -5 total: 0. You did a lot of work but I had 3 projects in prod with coroutines (+dozen tests) and nothing fundamentally changed, now I need to checkout that pack of libs to find that they are so alpha :)
I didn't watch the whole video but, I was curious about point 8, he tries to load data in onCreate without showing any kind of architecture? is that it?
At around 28:56 should this do the job also: suspend fun loadNote(): Note = viewModelScope.async { repository.loadNote() } I don't see the point on this CompletableDeferred. If it should be loaded only once you could use the lazy delegate. Why is CompletableDeffered needed?
it's about caching the returned value. notice that actual start of coroutine happens when viewmodel is created. in your example each call to the function will start new coroutine in scope of view model (instead of caller scope) which I'd guess kind of violates structured concurrency principle (if I understand it correctly ;))
It's crazy how much has changed in Android development in less than 4 years. It's like I learn something, and by the time I've mastered it something new is made to replace what I've just mastered. 🤯
To master background thread, how far is it! I just keep studying,studying,studying.....forever .....
I got called out saying RxJava is outdated 😆
yea but it's really getting better. I love the new stuff, much better than the verbose and clunky stuff I had to do before
yep
this is true :)
"suspend fun" sounds so sad... :(
At least we still got "private fun" ( ͡° ͜ʖ ͡°)
XeaLStorm how about “suspend private fun”
Yes
Suspend fun hahahah, that's very true.
very fitting tho
Kotlin documentation for coroutines sucks (to say the least)!
Kotlin docs for so many things sucks
yup :(
I had to literally read the the Design Document for the Coroutine library just not to understand 90% of the things.
Few years from now they will come up with new way for async programming and say coroutines sucks.
The goal is basically set at 4:26 but at the end of the video it feels like(as always) we are back to square one.
On the hindsight making anything comprehensive and simple with fragment + activity with their lifecycles is incredibly complex. Throw in a service(Which connects asynchronously and has its own foreground limitations) that needs to be connected and you have to throw everything out of the window.
Sorry but who are these developers you guys are supposedly talking to? How many completely different async solutions are there now for Android? Like 30? Do all these developers constantly want to learn new ways to perform async tasks?
I don't get how Coroutines are presented as an "easy" solution.. They are very hard instead to use properly. I'm trying get it but it's far from easy.. Am I the only one?
@@TMB_Randy Let me guess, you don't use RxJava either?
@@_AddSense_ I learned Rx1, then Rx2...not even finished the project I worked on & everybody started pushing coroutines and kt then I switched to backend so I don't have to relearn everything every couple of months. I also pushed hard at first for kotlin then I discovered I hate it because I was never getting NPE in java either but with KT it keeps bothering you with nonsense ! ? ... for now backend is quite nice and stable
after awhile I start to wonder if this stuff is inaccessible by design
Ouch, all this is so awfully complicated, I guess I will stick with good old callbacks.
so many methods and so many scopes. It feels like patch work rather than a complete solution to handling thread calls and orientation changes. Specially in case of fragment. I am sure in future a lot more stuff will come to fix what is done right now. IMHO fragments itself should be re-written. For a beginner this is a very steep learning curve.
true as a beginner my head is gonna explode now by seeing how fast the android libraries keep changing
do you seriously think that coroutines are easier than mvp with rx? I was expecting something really easy but got frustrated.
Wow! This session was just... perfect! Crazy how much easier and clearer this is compared to the workarounds devs had to do before, really shows how much we can improve tech even now. Really well explained and complete. Would be great if videos like these showing how to use a new feature from the ground up and relating it to other modern libraries were more common. Good work
About 30:00 , I don't understand how this works.
It runs this peace of code on the UI thread, on start, right?
So how come it waits for "note" variable to be fetched?
Does it also re-load the data this way, each time it gets changed, or does it load it just once?
so tell me how does this work with MVVM which has a repo, viewmodel and view !!!!
If you are still looking for it. They have these repository. github.com/android/architecture-samples
I don't event know what is better: write some boilerplate code but know what is going on, or learn a lot of new abstractions which you do not fully understand
ikr, developers has less control over the abstractions, and end up writing more boilerplate to handle them
the visuals are wonderful
Are there any complete samples on github?
Thanks guys. Very helpful. Have you shared the lecture notes?
23:46 yeah but cancelation is cooperative, the while loop has to check for isActive property of the coroutine and break from the loop.
At around 28:56 should this do the job also:
suspend fun loadNote(): Note = viewModelScope.async { repository.loadNote() }
I don't see the point on this CompletableDeferred. If it should be loaded only once you could use the lazy delegate.
Why is CompletableDeffered needed?
I think the video's code on that slide won't compile (can't check now) and I think the viewModelScope {...} call was meant to be put in an init {...} block. The difference with your code is that your code would only start executing when loadNote() is called. This means that the repository.loadNote() call is started later and therefore could complete later too.
However, this doesn't answer the difference between CompletableDeferred and just Deferred. A big difference is how they are built: Deferred is built using async {...} and CompletableDeferred through its constructor. The latter allows you to set its value (through the complete(...) function) from another place, which can be convenient if that place does more than just fetching one value asynchronously. Just using async {...} means you start one coroutine to get one value asynchronously as a Deferred. So in other words: it's the same, but CompletableDeferred used like on this slide is more flexible.
So the same, but different would have been:
class MyViewModel : ViewModel() {
val deferredNote = viewModelScope.async { repository.loadNote() }
fun loadNote() = deferredNote.await()
}
I have used viewModelScope since it released but now after upgrade dependence version of lifecycle to 2.2.0-alpha01, I can't see lifecycleScope or liveData block??? Please help me to try it.
I found it in the mvnrepository.
implementation "androidx.lifecycle:lifecycle-livedata-core-ktx:2.2.0-alpha01"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha01"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01"
With more focus on Rx in general, Google should show why a reactive paradigm is the way to go. RxJava is a solution for this, coroutines with Flow will also provide a way to achieve it. But this is my issue with comparing RxJava and Coroutines currently. They are not comparable.
I think Google's problem is that Flows neither are stable nor have they been used a lot, so they have to come up with something in the meantime. RxJava is the logical step in between, because it's popular, flexible and powerful. The differences with Kotlin coroutines of today are big, though, so that's precisely why this talk just ignores Rx.
Best explanation of coroutines i've seen!
i think the solution with an explicit context as used by go is easier to reason about than this hidden-in-the-background idea of cancellation.
Isn't the statement "Kotlin calls loadUser just like a normal function" sort of inaccurate? Wouldn't you need to use either launch or async, for instance? So when the loadUser suspend function is called, the first thing that gets "suspended", in the flow of things, would be that wrapping coroutine, right?
It would be great if they put the slides in somewhere
android development would soon require to be only attempted by stuntmen and Phds. Phds who possibly had two or three Masters in various fields of maths science and computations
Well, I guess you don't have to follow any of the principles or use the tools available. But it in the end, it's about making a high-quality application. These tools seem complex, but they actually reduce the complexity of an app, so one has to choose either implementing a "complex" architecture from the start, or maintain an app that because complex after growth.
Hi Team,
I hope you are doing great.
I want to clarify one doubt regarding Kotlin Coroutines.
How can I delay the execution of the next line or next block of code in my app until the response of my ongoing API comes?
Thanks in Advance !!!
Looking at the actual code of the LifecycleCoroutineScope, I don't think it works the way they claim. Specifically, I don't see any code that would cause coroutines started with 'launchWhenStarted' to suspend when the state is < STARTED. The only thing LifecycleCoroutineScope seems to actually do is cancel when the lifecycle owner is DESTROYED. I'm wondering how much of this talk is actually useable...
So I can say conclusively, from actual testing, that it *does* work. I don't get how it works, but it does.
@@DappOllone well, that's probably because onCreate is always (I think) followed by onStart, so, in reality, the only state that would prevent fragment transactions is onDestroy
Rx Java is very good to use with MVP
How do you guys test this much complicated scenarios?
how to communication corotines to UI in jetpack composables? because we can update UI only in composables
10:23 : transforming to another representation from stack to whatever is used for supsendables and then back when resuming, and copying stuff sounds a bit comp intensive, I don't see why we couldn't build separate substacks for the suspendables in the main stack and switching into them and back when necessary. no copying and transforming involved. or am I dumb and threads couldn't manage that and point to other substacks like that temporarily?
Also wai†ing for reply on this.
Because that way you wouldn't be able to access local variables from that stack. That's why lambdas in java copy local variables and not referencing them directly. Because of that you can only use final variables in java. In Kotlin, because you just put the coroutine stack back you can treat it as a single stack which not only simplifies things greatly for you but for the cpu too.
Android development has become a mess...
Always has been
It was super helpful 🙏
We're delighted to hear this, Mahmoud. Have you checked out our Kotlin Coroutines guide? See it here 📖 : goo.gle/3SGg08P
Things are like getting out of hand soon. It is more and more costly to understand and master Android app development. Even the Android software engineer at Google has hard time to explain the things in easy to understand way.
Ikr? I wonder what happened to intent service. Also Kotlin plays a huge part in that mountain of new things since the code doesn't look like java.
I had tried these "new" coroutines a while ago... hard to grasp... The first iteration of this was much simpler.... I understand what they want to do, but honestly.....
I think they should all be taken away from the development of any new feature for a couple of years, there really is no point now. And just let them fix their own mess and try to explain all of it as well.
I don't see any of these people writing books, writing interesting blogs.....
It just seems that software development is getting more and more 'magical' in order to fulfil some unknown need somewhere..... and moving towards tougher and tougher to grasp and to implement and to debug paradigms.... with little to no added value for the end result, which should be a humble app
to retrieve data from network and update the UI it's a such common problem that I would expect to have a easy way to solve it, considering common use cases like rotation or user switching apps, but apparently it always will be a complicated problem
Thanks for all those keynotes google
I agree, iti s interesting and useful. Thank you.
One of the best sessions by date
Kotlin discover async/await from C# #justKidding xD
coroutines appeared in 60s, it is not that new
and async/await is based on languages that exists before C#
ah.. why threading is so complicated
Computatations @ 3:39
Its interesting and usefully..Thanks
Sorry but worst talk ever. I could not be anymore confused.
1. CoroutineWorker - ok, I had to make Woker implement CoroutineScope before. +1
2. Retrofit - there is Adapter by Jack 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' +0
3. Room - ok, previously there was suspended fun in the Repo for this purpose. +0
4. LiveData with Coroutines - LiveData should be simple as F. -1
5. viewModelScope - Previously had to implement CoroutineScope. +1
6. lifecycleScope, when started - Good for Animations, Transitions, etc... +1
7. coroutines-test - Best part, trick with immediate delay is awesome! +3
8. Part where dude tried to get data in onCreate() - Uncle Bob would destroy you! -5
total: 0. You did a lot of work but I had 3 projects in prod with coroutines (+dozen tests) and nothing fundamentally changed, now I need to checkout that pack of libs to find that they are so alpha :)
I didn't watch the whole video but, I was curious about point 8, he tries to load data in onCreate without showing any kind of architecture? is that it?
Can’t wait to use these coroutine components.
I hear consolation instead of cancellation
Android devel fantastic
Google Writes the best code. You are so funny :)))))))))
Nice
thanks
Yes
Terrible audio quality 19:00
Just "exactly" like async/await from c# but let's just rename it.
And coroutinewroker = Task
Exactly like synchronous monads in haskell, lets just claim C# invented it.
Not exactly tho, there are really huge differences between them.
Sergey Strelcov lol
why 1_000 instead of 1000?
It's the same...
In Kotlin, you can seperate number by "_" to make it easier to read.
@@mithatsinansar3366 you can do the same in Java, starting from 1.7.
Cuz Kotlin
1st to comment.
Coroutines atlast
At around 28:56 should this do the job also:
suspend fun loadNote(): Note = viewModelScope.async { repository.loadNote() }
I don't see the point on this CompletableDeferred. If it should be loaded only once you could use the lazy delegate.
Why is CompletableDeffered needed?
it's about caching the returned value. notice that actual start of coroutine happens when viewmodel is created. in your example each call to the function will start new coroutine in scope of view model (instead of caller scope) which I'd guess kind of violates structured concurrency principle (if I understand it correctly ;))