LYLA FUJIWARA: So hello and welcome to the Android Dev
Summit 2019, and the second day of the #AskAndroid livestream.
We are here in the ADS sandbox.
My name is Lyla Fujiwara and I'm a developer advocate
for Android.
DAN GALPIN: Hi everyone, I'm Dan Galpin,
and it's great to be here at ADS '19.
If you're just tuning in, #AskAndroid
is our live segment where we answer questions
that you have submitted to us on Twitter
or on the YouTube livestream using the hashtag #AskAndroid.
LYLA FUJIWARA: And I want to take this chance
to give a big shout-out to all of you who
are watching on the livestream from around the world.
We've got viewers from India, Germany, Cameroon, Indonesia,
Canada, Turkey, the Philippines, Hungary, and Peru.
DAN GALPIN: And there's more.
Hi to those viewers in the UK, Bangladesh, Mexico, Nepal,
the Congo, Italy, Sudan, Pakistan,
Brazil, and the Netherlands.
LYLA FUJIWARA: Wow.
So that's amazing.
Thank you so much for watching.
DAN GALPIN: Now next up, to answer your questions
about Kotlin and coroutines on Android
are Florina Muntenescu and Sean McQuillan.
Now, Florina and Sean are both developer advocates
who work on Kotlin.
Florina also works on Architecture Components
and is a tech lead on Plaid, and when she's not doing that,
she leads the Kotlin Everywhere program.
Now, Sean works on MotionLayout.
He's the author of the kotlinx.coroutines test
library.
He's also the author of "Coroutines on Android,"
a blog post series, and is a Udacity instructor
for all of our current Kotlin offerings.
LYLA FUJIWARA: OK, so with all that, hopefully they
will be able to answer the Kotlin question.
So remember to tweet them-- keep tweeting them.
We're taking them live.
But the first question that I have for you all
is, what is your favorite Kotlin feature?
FLORINA MUNTENESCU: Ooh, can I start with this?
OK.
I would say a lot of the features
from the Kotlin standard library,
but I have one specific.
So I love extension functions, but all the extension functions
on collections, I just love those.
So I was doing so many things by hand--
all of those like math and group by and so on.
But now with Kotlin just being able to call
something that's implemented for me, it's perfect.
SEAN MCQUILLAN: I have to go with interface delegation.
It's like this weird esoteric feature
that you don't use that often, but when you do,
it saves you like 50 lines of code.
And it's probably my favorite like "wow, I
can't believe this worked" feature in Kotlin.
DAN GALPIN: That's awesome.
Yeah, I was going to say, I have my--
I really love the collection classes.
One of those things you don't immediately notice.
You're like, wait, I don't have to do all that work myself?
And you're just like, that's amazing!
So yeah, I totally concur there.
LYLA FUJIWARA: Cool.
DAN GALPIN: All right, so a question,
I think-- we just want to make sure our viewers know,
what are coroutines?
[LAUGHTER]
FLORINA MUNTENESCU: Can I answer this, Sean?
SEAN MCQUILLAN: Go for it.
[INTERPOSING VOICES]
DAN GALPIN: Oh yeah.
SEAN MCQUILLAN: So if I had to say at the highest
level of what coroutines are, they really
are a way to replace callbacks.
So when you normally make some code run on another thread
and then come back to the main thread,
you have to do something in order
to synchronize that result and return it back
to the main thread.
And the way you classically do this is with callbacks,
and that code can be a little bit verbose,
a little bit of boilerplate-y.
Coroutines kind of, like, simplify that code
and make it so you can do it all in-line
and write it as if you're writing sequential code that
never switched threads at all.
So they really kind of help simplify your ability
to do kind of background processing on Android.
LYLA FUJIWARA: OK, so with that in mind,
we got a sort of interesting question
that I slotted into the Kotlin segment, which is a little bit
funny.
But so the question is, from Johnny Mnemonic,
"What is the way to handle background threads in Android
with Java?
I'm asking this questions as the docs refer to AsyncTask--"
and then there's some, like, upset faces.
[LAUGHTER]
"--Looper/Handler, work manager, threads/runnables, executors,
maybe services."
And maybe we could add, like, can I use coroutines on Java
to that list?
So I don't know, what are your thoughts on that?
FLORINA MUNTENESCU: So step 1, convert your code to Kotlin
and then step 2, use coroutines?
SEAN MCQUILLAN: I mean, I definitely do recommend that.
But barring that, if you're using the Java programming
language, the simplest thing you can do
is to use ExecutorService, and that will let
you run code on the background.
You'll have to use callbacks to get results back
to the main thread.
And then the other option, really,
is to go into RxJava, which allows
you to have quite a bit of flexibility with how you
architect and build your application in the Java
programming language.
LYLA FUJIWARA: So do--
SEAN MCQUILLAN: I would not try to use coroutines from the Java
programming language.
Yeah, it's just not-- it's not a great interop story.
DAN GALPIN: And I think a big thing
here, too, is that WorkManager is kind of thrown in among all
those, and WorkManager is not a way to run things
on a background thread.
It's a way to schedule something that's run--
that would not run in your existing context necessarily.
And I think-- so I think there's a lot of confusion
about WorkManager, because we talk about background work,
but we're not really talking about multi-threading work.
LYLA FUJIWARA: So just to clarify, going back
to executors and RxJava and coroutines,
can we all think of those at about the same level?
FLORINA MUNTENESCU: Yeah, I will say so.
LYLA FUJIWARA: So those are just our--
FLORINA MUNTENESCU: For example, in RxJava,
you would use singles or completables.
I would use a Suspend Function coroutines.
LYLA FUJIWARA: Cool.
DAN GALPIN: All right, so Mark Andar
asks, I'd love to see some sample code or Jetpack
support using coroutines or channels to lazily provide data
to a RecyclerView adapter, like with a progress spinner
or something like that.
FLORINA MUNTENESCU: So from what I know for now,
we don't have something like this,
but actually that's a good idea of another use case
that we should support.
DAN GALPIN: Now, do you think channels,
or would you use Flow?
Like what-- when you're thinking about this kind of use case?
FLORINA MUNTENESCU: I would use flows, but--
Sean, what's the difference between channels and flows?
SEAN MCQUILLAN: Yeah, so particularly for this use case,
yeah, I agree, I would also use flows.
And the real difference between them
is-- the way to think about it is you should use channels
when you're expecting to transfer a value between two
threads, and you would maybe reach for,
like, a blocking queue if you were doing basic thread
programming.
So that's really where channels really shine,
and they do suspend both sides if the queue's full.
Whereas a flow's really better served,
I think, for this use case of, I have some data,
it's updating over time, and I'd like
to pass that up to the screen.
LYLA FUJIWARA: All right.
So Arif from the livestream asks "What
are the differences between Java threads and Kotlin coroutines?"
SEAN MCQUILLAN: What are the differences between Java
threads and Kotlin coroutines.
So it's one of those like kind of complicated questions,
because it goes really deep.
But it's really when it comes down to it,
the threading model basically does not
allow, in the threading model, to pass values
at the end of a thread.
Like, you don't launch a thread, do some computations,
and then get a result out of it.
You always have to add this callback interface every time
you want to pass values between threads.
Whereas coroutines-- they do allow
you to use the threading model in Android,
but you're allowed to pass values more simply
by using the coroutine's implementation
in the programming language.
LYLA FUJIWARA: So basically, coroutines cover more.
Like--
SEAN MCQUILLAN: Yeah, yeah, they simplify things.
Yeah.
FLORINA MUNTENESCU: More lightweight than threads.
DAN GALPIN: Yeah.
And they're not even necessarily bound
to threads-- it's really a mechanism for calling
this kind of thing.
We just happen to use a thread-bound implementation.
OK, so another one from the livestream.
NikkiThompson27 asked "Is there a difference between the use
cases that LiveData and Coroutine Flow support?"
FLORINA MUNTENESCU: Yeah so what I like about LiveData
is that it's really connected to the UI, right?
So you have to pass-- when you're absorbing it,
you have to pass a life cycle.
Whereas, let's say by default, when
you're thinking about coroutines,
you don't really have that.
But what coroutines brings is scopes,
so you would run a coroutine in a scope.
So you could say this is a similarity between LiveData
and coroutines.
But then I think we were talking about use cases as well?
DAN GALPIN: Yes, use cases, exactly.
FLORINA MUNTENESCU: What I like about coroutines
is that you can use them away from something
that's very specific to an activity or a fragment.
LiveData also allows you to do that, but not
as easily as a coroutine would.
Yeah.
DAN GALPIN: So in terms of your architecture, then,
would coroutines be something you'd
be happier putting into your repository layer, then?
FLORINA MUNTENESCU: Yes.
Yeah, I would use coroutines from the database,
because now we also have room support for coroutines
up until the view model.
And then maybe only in the view model,
I would make that connection to LiveData
and use the LiveData between the view model and the UI.
LYLA FUJIWARA: So maybe a more specific example of this.
So Adam Sherwitz asked "Is it acceptable
to pass a coroutines scope into a repository as a param?
The use case being Room calls nested inside an async Firebase
listener like the OnComplete-- addOnCompleteListener.
SEAN MCQUILLAN: Yeah, I mean, I think in general,
you shouldn't really be concerned
about sharing coroutine scopes.
They're kind of lightweight objects.
They naturally encapsulate a life cycle, and they' really--
if you go dig into the implementation,
it's like two references.
It's a really lightweight object,
so you should feel pretty comfortable keeping them.
This specific use case, though, I
would say it's also a really good idea
to consider whether Flow is going to fit there as well.
It sounds like maybe a callback flow
is going to be able to solve that really, really well,
and maybe you won't have to pass the coroutine scope.
FLORINA MUNTENESCU: Yeah, I think
it's about really understanding what you're trying to do.
So if it's a database operation, chances
are you want this to be related to maybe
the activity-- the application scope,
not just the activity scope.
You want to make sure that wherever
data you're maybe saving in your database
is really saved independent on whether your user pressed
Back or not.
So yeah.
Keep these things in mind.
DAN GALPIN: OK, so another question that
came in from the livestream--
is there any good example from Google
for showcasing usage of Kotlin coroutines
with Android Architecture Components,
with like an MVVM pattern?
FLORINA MUNTENESCU: I actually think we
have a lot of things for that.
So we have several samples on the Architecture Components
Github repository, but then we also
have I think several code labs.
I think we're also using them in our Udacity courses.
I know that we have several articles that also
cover some of these things.
What am I missing, Sean?
SEAN MCQUILLAN: Yeah, I mean, that's it.
I'd also mention that there's the LiveData Builder
sample as well.
FLORINA MUNTENESCU: Exactly.
SEAN MCQUILLAN: Yeah.
And there's a whole architecture behind the LiveData.
LYLA FUJIWARA: There was a talk at I/O
about this, too, specifically, right?
Like new sort of Architecture Components plus coroutines
and some develop--
documentation pages as well.
SEAN MCQUILLAN: I'd also mention Jose and Yigit just
gave a talk at this conference.
LYLA FUJIWARA: At this conference here.
SEAN MCQUILLAN: You can find it YouTube.
LYLA FUJIWARA: Live!
SEAN MCQUILLAN: So you can check out that talk.
It covers how to use Flow with Architecture Components
as well.
DAN GALPIN: Great.
LYLA FUJIWARA: OK, awesome.
All right, so I want to-- all right.
Ugh.
Tasomaniac asks "Will Google's Dagger
ever be Kotlin or Android Architecture Components
friendly?"
So maybe focusing on the Kotlin part of that.
I know-- and we'll skip the rest of that.
FLORINA MUNTENESCU: So I hope--
Sayid, if I'm not mistaken, hasn't seen that talk
that just happened before.
It was on dependency injection in Android.
Because one of the things that are mentioned there
in that talk is that we're working actually on improving
Dagger and Kotlin support.
So for example, right now you have
to add several JVM-specific annotations
to some modules or some fields in your modules,
and that's something that we want to remove.
Or for example, for qualifiers, you
have to do something like Add Field and then the qualifier
name, where we want to remove that field for you
and then let Dagger do all of that magic.
So I would say coming up soon in a Dagger library next to you.
DAN GALPIN: Stay tuned for more.
LYLA FUJIWARA: And I think we're having Yigit and [INAUDIBLE] on
to talk next and we're definitely
going to touch on this a little bit more,
so stay tuned for that as well.
DAN GALPIN: All right, so here's a question.
"How do you coroutines handle exceptions?"
This is from UGenU, by the way, on the livestream.
SEAN MCQUILLAN: So like at the highest level, the way
to think about this-- it's kind of like a thing to think,
they just throw exceptions the way
that exceptions normally work.
So like when an exception gets thrown,
it kind of unrolls the stack, and then there's
an exception handler and you catch it
in that exception handler.
So that's-- when you're coding with coroutines,
you just code that way and it works.
The way that actually works if you dive a little bit deeper,
is what the coroutine does is when the exception gets
thrown, if it was suspended at some point previously,
it resumes that coroutine with an exception.
And when it resumes.
It immediately throws the exception,
kind of keeping as much of the stack
trace as it can piece together on the way there.
DAN GALPIN: It's great, because it means that you can actually
just treat it like ordinary code, which
is really important.
SEAN MCQUILLAN: Exactly.
LYLA FUJIWARA: OK, so "AlfredEITears," or EITers,
asks "Me and my team are quite used
to using RxJAva and Kotlin for managing
asynchronous work in IO.
I'm always striving to test new technologies,
so coroutines and Flow has surely caught my attention.
What would be your top reasons to move away
from Rx and into coroutines?
SEAN MCQUILLAN: I actually have no top reasons
to move away from Rx and into coroutines.
I think if you have a large existing code
base using RxJava, you know, that's awesome.
And you know, that's a really great solution
that works for lots and lots of people.
So I don't think there's any reason to, like,
prioritize rewriting your code base
if you're happy with RxJava.
FLORINA MUNTENESCU: But if you're starting a new app,
I would say go with the coroutines.
I think a lot of the things that RxJava
does, like completable and single, these are very,
as I was saying, similar to the suspend functions,
and they're more lightweight.
I know that a lot of times, people
end up misusing RxJava, so starting a new observable
or single just to do an operation on the background
thread.
So I would say maybe also make sure
that you're using RxJava for the right reasons,
and then if you're not doing that,
consider going more towards coroutines.
DAN GALPIN: Do you think there's any value in having
a pure Kotlin code base?
I know there's, like, build times,
there's maybe a little bit of value.
But--
FLORINA MUNTENESCU: Hmm.
I think it's-- yeah, build times, I know, it's one.
And plus you don't have to do that switch between Java
and Kotlin.
I know I realize now, when I try to write a Java code,
that I'm like, what am I missing?
Oh, I'm missing the new keyword.
OK.
[LAUGHTER]
So there's this as well.
So I think there's that extra mind--
LYLA FUJIWARA: Like context switch.
FLORINA MUNTENESCU: --context switch.
DAN GALPIN: Yeah.
FLORINA MUNTENESCU: And yeah.
What do you think, Sean?
SEAN MCQUILLAN: Semicolons.
DAN GALPIN: I love--
[INTERPOSING VOICES]
DAN GALPIN: --semicolons, I was going
to say exactly the same thing.
FLORINA MUNTENESCU: Yeah.
LYLA FUJIWARA: Yeah, so I guess sort of again
with, like, RxJava and coroutines,
you can say that this isn't a fair comparison,
but do you think one is easier to pick up
than another if you're just kind of starting off with this?
SEAN MCQUILLAN: So one of the things-- one
of the reasons we really like coroutines is because they-- it
scales, really, both ways.
So it's like-- it's very easy to use coroutines
to do very simple things, to make a one shot network request
and display that result in the UI.
When you're first starting out with asynchronous programming--
which everyone has to do, because everyone
has to do network programming.
And then it also scales to the other side.
When you're building, like, large,
complex applications, some of the top apps in the Android app
store can easily use coroutines to build large architectures
that work for them.
And so that's something that's really
amazing about coroutines, is they're kind of easier
to use in the first usage, and they also scale
to very complex usages as well.
LYLA FUJIWARA: Cool.
DAN GALPIN: So this is a question
that came in from the livestream from Alfred.
"The Rx--" as in reactive extensions--
"are available for Java, .Net, JavaScript.
Is there an Rx for Kotlin?"
FLORINA MUNTENESCU: I think--
SEAN MCQUILLAN: There's an RxKotlin library.
DAN GALPIN: There is an RxKotlin library.
I was just curious--
SEAN MCQUILLAN: I haven't used it myself, to be honest.
DAN GALPIN: Yeah, neither have I, unfortunately.
So to get-- so yes?
LYLA FUJIWARA: It's there?
Yeah, tell us what you think about it.
DAN GALPIN: Yeah.
LYLA FUJIWARA: OK, cool.
Let's see.
All right, so here's one.
"I've started to sort of upscale on testing.
How do you test with coroutines?"
DAN GALPIN: Why are you asking me about--
[INTERPOSING VOICES]
LYLA FUJIWARA: Do you know anything about that?
SEAN MCQUILLAN: So there's like-- there's basically--
so testing with coroutines, there's
basically like two different ways
you might go around testing with coroutines.
You can kind of treat coroutines as a thing that just executes
like kind of in a background thread, and then you just spin
and you wait for the result to come in.
This is kind of like behavioral testing, which
is a really good way to test kind
of the correctness of a large coroutine unit.
And then when you want to get more fine detailed
and you want to test specific concurrency in coroutines,
which is going to come up as you build larger coroutine code
bases, there is a library of Kotlinx coroutine tests--
we're going to have a talk about it later today.
It'll be on YouTube tomorrow, probably--
where you can use that to basically control
the specific execution of a coroutine, which
is really helpful to make sure that your tests, like--
you know, doesn't randomly do a different execution order
and flake out and stuff like that.
And also for getting really down in the details--
I mean, like I need this to happen and then that to happen
and then that happen--
and make sure that you're testing
exactly the weird specific concurrency
bug that you want to check.
FLORINA MUNTENESCU: Ooh, I can't wait to see your talk.
DAN GALPIN: I know.
LYLA FUJIWARA: Yeah, the reason I
was being so snarky about that is because Sean wrote
large portions of that library, which is also
another reason if you have more testing questions,
you should definitely-- with coroutines, please let us know.
We'll try to answer them for you.
DAN GALPIN: So another question from the livestream from Arif,
thank you, is "Is there any performance overhead
with Kotlin Coroutines?"
And I guess, really, that's probably
comparison to other methods, I think, as doing similar things.
There's obviously some performance overhead.
SEAN MCQUILLAN: Yeah.
So comparing them to callbacks is,
I think, where coroutines really should be compared to when
we talk about performance.
They're competitive with callbacks.
So if you use executors, you use RxJava,
you're going to find competitive performance
to all of the callback invocations
that you have in those libraries.
Comparing them to regular functions,
they do have performance overhead the same way
that callbacks have performance overhead,
and so it's worth keeping that in mind
if you're doing something like reading the character
from a network buffer--
and you're going to do that a couple of million times--
that might be better as a regular function.
So there is-- it works great in application code.
When you start writing the library code,
you should be aware of the cost of coroutines.
DAN GALPIN: That's great.
LYLA FUJIWARA: OK.
Sorry, I think we did answer one of these.
So Rora's asking, will there ever
be coroutines for Java, which we answered
a little bit before the--
right now.
DAN GALPIN: Why don't we just ask this question here,
just because we're-- yeah.
LYLA FUJIWARA: Well, I think-- yeah,
so I think we're going to be wrapping up soon.
We're sort of seeing from the back that that's the case.
We're close to being out of time,
so I do want to thank Sean and Florina for being on camera
with us today and for sharing all of their Kotlin knowledge
and insights.
So if the viewers out there want to learn more about Kotlin,
they want to learn more about coroutines,
what should they do?
Where should they go?
FLORINA MUNTENESCU: I would say start
with developer.android.com, then check out our code labs,
the Udacity courses, the Medium articles.
What else?
SEAN MCQUILLAN: Yeah, and we have several samples.
We have the IO Sketch sample, we have Plaid.
So yeah, check those out.
FLORINA MUNTENESCU: Sunflower, yeah.
And the talks-- I think we've been giving talks
on how to work with Kotlin and with coroutines in Android,
both at Google I/O and of course at ADS.
LYLA FUJIWARA: Yeah, what are some good talks from ADS
that maybe we should check out?
SEAN MCQUILLAN: Oh, so we have Jose and Yigit's talk
about Flow.
We're going to have a coroutines testing talk.
And then were there any Kotlin-specific talks?
FLORINA MUNTENESCU: Yes, actually, there
is one on Kotlin and Java, I think?
LYLA FUJIWARA: Yes.
SEAN MCQUILLAN: Oh yeah, Nicole, yeah.
LYLA FUJIWARA: Yeah, Nicole's doing
a talk on Kotlin and Java.
FLORINA MUNTENESCU: Today.
SEAN MCQUILLAN: Yes.
LYLA FUJIWARA: So definitely check that out.
FLORINA MUNTENESCU: Check that out.
LYLA FUJIWARA: And if you're willing to--
if you're willing.
If you would like to see people in the flesh
and work with them with Kotlin-related stuff,
Kotlin Everywhere is still going on,
so you should definitely take a look at that.
If you just Google "Kotlin Everywhere,"
you'll be able to find events around you.
DAN GALPIN: Awesome.
Thanks once again for being with us,
and remember to keep asking your question using the hashtag
#AskAndroid.
And we'll be right back with Yigit and Jisha
to talk about Architecture Components.
[MUSIC PLAYING]