SlideShare ist ein Scribd-Unternehmen logo
1 von 66
Kotlin Coroutines ïŒˆć…„é–€ïŒ‰
CHOCOTV
Louis & Timmy
Android Taipei 20181024
Topics
● Asynchronous
● suspend
● async/await
● Android
○ network
○ lifecycle
○ performance
● QA
Asynchronous
fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
fun getToken(userId : String) : String
fun getUserName(token : String) : String
fun sendMessage(message : String) : String
fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
fun getToken(userId : String) : String
fun getUserName(token : String) : String
fun sendMessage(message : String) : String
fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
@WorkThread
fun getToken(userId : String) : String
@WorkThread
fun getUserName(token : String) : String
fun sendMessage(message : String) : String
fun test(userId:String, callback:()->Unit){
getToken(userId) token-> {
getUserName(token) userName->{
sendMessage("User id is $userId and name is $userName"){
callback.invoke()
}
}
}
}
fun getToken(userId : String , callback:(String)->Unit)
fun getUserName(token : String , callback:(String)->Unit)
fun sendMessage(message : String , callback:(String)->Unit)
fun test(userId:String, callback:()->Unit){
getToken(userId) token-> {
getUserName(token) userName->{
sendMessage("User id is $userId and name is $userName"){
callback.invoke()
}
}
}
}
fun getToken(userId : String , callback:(String)->Unit)
fun getUserName(token : String , callback:(String)->Unit)
fun sendMessage(message : String , callback:(String)->Unit)
Callback hell
fun test(userId:String, callback:()->Unit){
getToken(userId) token-> {
getUserName(token) userName->{
sendMessage("User id is $userId and name is $userName"){
callback.invoke()
}
}
}
}
fun getToken(userId : String) : Single<String>
fun getUserName(token : String) : Single<String>
fun sendMessage(message : String)
fun test(userId:String){
getToken(userId)
.flatMap {
return@flatMap getUserName(it)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
sendMessage("User id is $userId and name is $userName")
}, {
//error handling
})
}
fun sendMessage(userId:String){
getToken(userId)
.flatMap {
return@flatMap getUserName(it)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
sendMessage("User id is $userId and name is $userName")
}, {
//error handling
})
}
fun test(userId:String){
getToken(userId)
.flatMap {
return@flatMap getUserName(it)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
sendMessage("User id is $userId and name is $userName")
}, {
//error handling
})
}
fun sendMessage(userId:String){
1. val token = getToken(userId)
2. val userName = getUserName(token)
3. sendMessage("User id is $userId and name is $userName")
}
What we want
Sequential
Suspend
suspend fun getToken(userId : String) : String
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String) : String
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
suspend fun getToken(userId : String) : String {
// do request & suspend
return token
}
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String) : String
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
suspend fun getToken(userId : String) : String
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String)
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
Like Regular code !!
suspend fun getToken(userId : String) : String
suspend fun getUserName(token : String) : String
suspend fun sendMessage(message : String)
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and name is $userName")
}
Like Regular code !!
How does it work ??
Let’s get deeper
suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
befroe
suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
Kotlin bytecode for jvm
suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
After
suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
After
suspend fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object
fun getToken(userId : String) : String
public final getToken(Ljava/lang/String;)Ljava/lang/String;
Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
Direct Style
Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
Direct Style
Continuation
Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
Continuation-passing style
In functional programming, continuation-passing style (CPS) is a style of
programming in which control is passed explicitly in the form of a continuation
fun test( ){
val token = requestToken()
val userId = getUserId(token)
}
fun test( ){
getToken { token->
val userId = getUserId(token)
}
}
CPS == Callback
How does it work
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
class test(userId:String , sm : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun resume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
spending function
class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun doResume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId, sm )
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName = getUserName(token)
sendMessage("User id is $userId and
name is $userName")
}
Restore state
class test(userId:String , callback : Continuation<Unit>) : Any{
val sm = CoroutineImpl {
fun resume(...){
test(null,this)
}
var token : String
var userName : String
}
switch(sm.Label){
case 0:
sm.Label = 1
getToken(userId,sm)
break
case 1:
sm.Label = 2
getUserName(sm.token , sm)
break
case 2:
sm.Label = 3
sendMessage("User id is $userId and name is $userName")
break
}
}
suspend fun test(userId:String){
val token = getToken(userId)
val userName =
getUserName(token)
sendMessage("User id is $userId
and name is $userName")
}
Android
Retrofit
kotlin version 1.3
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
kotlin version pre-1.3
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0'
val retrofit = Retrofit.Builder()
.baseUrl("https://example.com/")
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
Retrofit
interface MyService {
@GET("/user")
fun getUser(): Deferred<User>
}
Retrofit
interface MyService {
@GET("/user")
fun getUser(): Deferred<User>
}
Retrofit
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser()
withContext(Dispatchers.Main) {
showMesssgae(data.await().message)
}
}
Retrofit
interface MyService {
@GET("/user")
fun getUser(): Call<User>
}
Retrofit
suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont ->
cont.invokeOnCancellation {
if (cont.isCancelled) {
cont.cancel()
}
}
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable) {
cont.resumeWithException(t)
}
override fun onResponse(call: Call<T>?, response: Response<T>) {
if (response.isSuccessful) {
val body = response.body()
?: return cont.resumeWithException(NullPointerException())
cont.resume(body)
} else {
cont.resumeWithException(HttpException(response))
}
}
})
}
Retrofit
suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont ->
cont.invokeOnCancellation {
if (cont.isCancelled) {
cont.cancel()
}
}
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable) {
cont.resumeWithException(t)
}
override fun onResponse(call: Call<T>?, response: Response<T>) {
if (response.isSuccessful) {
val body = response.body()
?: return cont.resumeWithException(NullPointerException())
cont.resume(body)
} else {
cont.resumeWithException(HttpException(response))
}
}
})
}
Retrofit
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser().await()
withContext(Dispatchers.Main) {
showMesssgae(data.message)
}
}
Retrofit
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser().await()
withContext(Dispatchers.Main) {
showMesssgae(data.message)
}
}
// Call<T>.await is extension function retrun data
Error handling
GlobalScope.launch(Dispatchers.IO) {
try {
val data = APIRepo.getUser()
withContext(Dispatchers.Main) {
showMesssgae(data.message)
}
}catch(e : Exception){
// error
}
}
How to cancel ?
val job = GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser()
withContext(Dispatchers.Main) {
showMesssgae(data.message)
}
}
job.cancel()
// RxJava Disposable
How to cancel ?
job.cancel()
Job Job 

.. n
class MainActivityTest : AppCompatActivity(),
CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
GlobalScope.launch(coroutineContext)
{
//do async
}
GlobalScope.launch(coroutineContext) {
//do async
}
GlobalScope.launch(coroutineContext) {
//do async
}
Concurrently
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser() // Deferred
withContext(Dispatchers.Main) {
showMesssgae(data.await().message)
}
}
Concurrently
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser() // Deferred
val dataNew = APIRepo.getUserNew() // Deferred
val dataNewTwo = APIRepo.getUserNewTwo() // Deferred
withContext(Dispatchers.Main) {
showMesssgae(data.await().message)
}
}
Concurrently
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser() // Deferred
val dataNew = APIRepo.getUserNew() // Deferred
val dataNewTwo = APIRepo.getUserNewTwo() // Deferred
withContext(Dispatchers.Main) {
showMesssgae(data.await().message)
}
}
Concurrently
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser() // Deferred
val dataNew = APIRepo.getUserNew() // Deferred
val dataNewTwo = APIRepo.getUserNewTwo() // Deferred
withContext(Dispatchers.Main) {
showMesssgae(data.await().message,dataNew.await().message,dataNewTwo.await().message)
}
}
Performance
Reference :
https://proandroiddev.com/kotlin-coroutines-vs-rxjava-an-initial-performance-test-68160cfc6723
GlobalScope.launch(Dispatchers.IO) {
val data = APIRepo.getUser() // Deferred
withContext(Dispatchers.Main) {
showMesssgae(data.await().message)
}
}
Recap
● Asynchronous
● Apk Siz & Method count
● Performance
● Readable
● Cost
Recap
● Asynchronous
● Apk size & Method count
● Performance
● Readable
● Cost
Recap
● Asynchronous
● Apk Siz & Method count
● Performance
● Readable
● Cost
Recap
● Asynchronous
● Apk Siz & Method count
● Performance
● Readable
● Cost
Recap
● Asynchronous
● Apk Siz & Method count
● Performance
● Readable
● Cost
Q & A
Thank you
Reference
https://kotlinlang.org/docs/reference/coroutines-overview.html
https://www.youtube.com/watch?v=_hfBv0a09Jc
https://www.youtube.com/watch?v=YrrUCSi72E8&t=707s

Weitere Àhnliche Inhalte

Was ist angesagt?

Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014
Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014
Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014
Baruch Sadogursky
 
Message
MessageMessage
Message
Togeiro26
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data Structures
PDX Web & Design
 

Was ist angesagt? (20)

Láș­p trĂŹnh Python cÆĄ báșŁn
Láș­p trĂŹnh Python cÆĄ báșŁnLáș­p trĂŹnh Python cÆĄ báșŁn
Láș­p trĂŹnh Python cÆĄ báșŁn
 
The Ring programming language version 1.10 book - Part 56 of 212
The Ring programming language version 1.10 book - Part 56 of 212The Ring programming language version 1.10 book - Part 56 of 212
The Ring programming language version 1.10 book - Part 56 of 212
 
Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017
 
FRP: What does "declarative" mean
FRP: What does "declarative" meanFRP: What does "declarative" mean
FRP: What does "declarative" mean
 
Groovy ネタ NGK 濘ćčŽäŒš2009 ăƒ©ă‚€ăƒˆăƒ‹ăƒłă‚°ăƒˆăƒŒă‚Ż
Groovy ネタ NGK 濘ćčŽäŒš2009 ăƒ©ă‚€ăƒˆăƒ‹ăƒłă‚°ăƒˆăƒŒă‚ŻGroovy ネタ NGK 濘ćčŽäŒš2009 ăƒ©ă‚€ăƒˆăƒ‹ăƒłă‚°ăƒˆăƒŒă‚Ż
Groovy ネタ NGK 濘ćčŽäŒš2009 ăƒ©ă‚€ăƒˆăƒ‹ăƒłă‚°ăƒˆăƒŒă‚Ż
 
DDS-20m
DDS-20mDDS-20m
DDS-20m
 
Broken windows de prĂĄticas ĂĄgeis
Broken windows de prĂĄticas ĂĄgeisBroken windows de prĂĄticas ĂĄgeis
Broken windows de prĂĄticas ĂĄgeis
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
 
Voce Tem Orgulho Do Seu Codigo
Voce Tem Orgulho Do Seu CodigoVoce Tem Orgulho Do Seu Codigo
Voce Tem Orgulho Do Seu Codigo
 
PyTrening 2.0 # 15 Okienka GUI
PyTrening 2.0 # 15 Okienka GUIPyTrening 2.0 # 15 Okienka GUI
PyTrening 2.0 # 15 Okienka GUI
 
Python AsĂ­ncrono - Async Python
Python AsĂ­ncrono - Async PythonPython AsĂ­ncrono - Async Python
Python AsĂ­ncrono - Async Python
 
PureScript & Pux
PureScript & PuxPureScript & Pux
PureScript & Pux
 
Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014
Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014
Groovy puzzlers ĐżĐŸ руссĐșĐž с Joker 2014
 
Ű§ŰłÙ„Ű§ÛŒŰŻ Ű§ÙˆÙ„ ŰŹÙ„ŰłÙ‡ Ú†Ù‡Ű§Ű±Ù… Ú©Ù„Ű§Űł ÙŸŰ§ÛŒŰȘون ŰšŰ±Ű§ÛŒ Ù‡Ú©Ű±Ù‡Ű§ÛŒ Ù‚Ű§Ù†ÙˆÙ†ÛŒ
Ű§ŰłÙ„Ű§ÛŒŰŻ Ű§ÙˆÙ„ ŰŹÙ„ŰłÙ‡ Ú†Ù‡Ű§Ű±Ù… Ú©Ù„Ű§Űł ÙŸŰ§ÛŒŰȘون ŰšŰ±Ű§ÛŒ Ù‡Ú©Ű±Ù‡Ű§ÛŒ Ù‚Ű§Ù†ÙˆÙ†ÛŒŰ§ŰłÙ„Ű§ÛŒŰŻ Ű§ÙˆÙ„ ŰŹÙ„ŰłÙ‡ Ú†Ù‡Ű§Ű±Ù… Ú©Ù„Ű§Űł ÙŸŰ§ÛŒŰȘون ŰšŰ±Ű§ÛŒ Ù‡Ú©Ű±Ù‡Ű§ÛŒ Ù‚Ű§Ù†ÙˆÙ†ÛŒ
Ű§ŰłÙ„Ű§ÛŒŰŻ Ű§ÙˆÙ„ ŰŹÙ„ŰłÙ‡ Ú†Ù‡Ű§Ű±Ù… Ú©Ù„Ű§Űł ÙŸŰ§ÛŒŰȘون ŰšŰ±Ű§ÛŒ Ù‡Ú©Ű±Ù‡Ű§ÛŒ Ù‚Ű§Ù†ÙˆÙ†ÛŒ
 
Message
MessageMessage
Message
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data Structures
 
4Developers 2015: Testowanie ze Spockiem - Dominik Przybysz
4Developers 2015: Testowanie ze Spockiem - Dominik Przybysz4Developers 2015: Testowanie ze Spockiem - Dominik Przybysz
4Developers 2015: Testowanie ze Spockiem - Dominik Przybysz
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
The Ring programming language version 1.3 book - Part 43 of 88
The Ring programming language version 1.3 book - Part 43 of 88The Ring programming language version 1.3 book - Part 43 of 88
The Ring programming language version 1.3 book - Part 43 of 88
 

Ähnlich wie Kotlin coroutines

мроĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»
мроĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»ĐźŃ€ĐžĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»
мроĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»
e-Legion
 
About java
About javaAbout java
About java
Jay Xu
 

Ähnlich wie Kotlin coroutines (20)

Kotlin의 ìœ”ëŁší‹Žì€ ì–Žë–»êȌ 동작하는가
Kotlin의 ìœ”ëŁší‹Žì€ ì–Žë–»êȌ 동작하는가Kotlin의 ìœ”ëŁší‹Žì€ ì–Žë–»êȌ 동작하는가
Kotlin의 ìœ”ëŁší‹Žì€ ì–Žë–»êȌ 동작하는가
 
First few months with Kotlin - Introduction through android examples
First few months with Kotlin - Introduction through android examplesFirst few months with Kotlin - Introduction through android examples
First few months with Kotlin - Introduction through android examples
 
200819 NAVER TECH CONCERT 03_화렀한 ìœ”ëŁší‹ŽìŽ 낮 앱을 감싞넀! ìœ”ëŁší‹ŽìœŒëĄœ ìž‘ì„±í•ŽëłŽëŠ” êč”끔한 ëč„동Ʞ 윔드
200819 NAVER TECH CONCERT 03_화렀한 ìœ”ëŁší‹ŽìŽ 낮 앱을 감싞넀! ìœ”ëŁší‹ŽìœŒëĄœ ìž‘ì„±í•ŽëłŽëŠ” êč”끔한 ëč„동Ʞ 윔드200819 NAVER TECH CONCERT 03_화렀한 ìœ”ëŁší‹ŽìŽ 낮 앱을 감싞넀! ìœ”ëŁší‹ŽìœŒëĄœ ìž‘ì„±í•ŽëłŽëŠ” êč”끔한 ëč„동Ʞ 윔드
200819 NAVER TECH CONCERT 03_화렀한 ìœ”ëŁší‹ŽìŽ 낮 앱을 감싞넀! ìœ”ëŁší‹ŽìœŒëĄœ ìž‘ì„±í•ŽëłŽëŠ” êč”끔한 ëč„동Ʞ 윔드
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
Introduction kot iin
Introduction kot iinIntroduction kot iin
Introduction kot iin
 
Controle de estado
Controle de estadoControle de estado
Controle de estado
 
Introduction Ă  Dart
Introduction Ă  DartIntroduction Ă  Dart
Introduction Ă  Dart
 
Kotlin
KotlinKotlin
Kotlin
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
Php sql-android
Php sql-androidPhp sql-android
Php sql-android
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
iOS Talks 1 - CodeCamp Osijek - Swift u praksi
iOS Talks 1 - CodeCamp Osijek - Swift u praksiiOS Talks 1 - CodeCamp Osijek - Swift u praksi
iOS Talks 1 - CodeCamp Osijek - Swift u praksi
 
мроĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»
мроĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»ĐźŃ€ĐžĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»
мроĐč Đ‘ŃƒŃĐœĐŸĐČ Â«Squeryl — ORM с Ń‡Đ”Đ»ĐŸĐČДчДсĐșĐžĐŒ Đ»ĐžŃ†ĐŸĐŒÂ»
 
Server Side Swift with Swag
Server Side Swift with SwagServer Side Swift with Swag
Server Side Swift with Swag
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
About java
About javaAbout java
About java
 
ă€ăăŁăŠă‚ăăŒ Kotlin DSL 珏2版
ă€ăăŁăŠă‚ăăŒ Kotlin DSL 珏2ç‰ˆă€ăăŁăŠă‚ăăŒ Kotlin DSL 珏2版
ă€ăăŁăŠă‚ăăŒ Kotlin DSL 珏2版
 
Finagle By Twitter Engineer @ Knoldus
Finagle By Twitter Engineer @ KnoldusFinagle By Twitter Engineer @ Knoldus
Finagle By Twitter Engineer @ Knoldus
 

Mehr von TSE-JU LIN(Louis) (7)

Mulit cdn exoplayer
Mulit cdn exoplayerMulit cdn exoplayer
Mulit cdn exoplayer
 
Android instant apps, step by-step: how CHOCOTV went about it
Android instant apps, step by-step: how CHOCOTV went about itAndroid instant apps, step by-step: how CHOCOTV went about it
Android instant apps, step by-step: how CHOCOTV went about it
 
Chromecast v3
Chromecast v3Chromecast v3
Chromecast v3
 
Exoplayer 2
Exoplayer  2Exoplayer  2
Exoplayer 2
 
2017.03.20 android taipei
2017.03.20 android taipei2017.03.20 android taipei
2017.03.20 android taipei
 
2017.02.22 android taipei
2017.02.22 android taipei2017.02.22 android taipei
2017.02.22 android taipei
 
20160929 android taipei Sonatype nexus on amazon ec2
20160929 android taipei Sonatype nexus on amazon ec2 20160929 android taipei Sonatype nexus on amazon ec2
20160929 android taipei Sonatype nexus on amazon ec2
 

KĂŒrzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

KĂŒrzlich hochgeladen (20)

Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 

Kotlin coroutines

  • 2. Topics ● Asynchronous ● suspend ● async/await ● Android ○ network ○ lifecycle ○ performance ● QA
  • 4.
  • 5. fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") } fun getToken(userId : String) : String fun getUserName(token : String) : String fun sendMessage(message : String) : String
  • 6. fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") } fun getToken(userId : String) : String fun getUserName(token : String) : String fun sendMessage(message : String) : String
  • 7. fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") } @WorkThread fun getToken(userId : String) : String @WorkThread fun getUserName(token : String) : String fun sendMessage(message : String) : String
  • 8. fun test(userId:String, callback:()->Unit){ getToken(userId) token-> { getUserName(token) userName->{ sendMessage("User id is $userId and name is $userName"){ callback.invoke() } } } } fun getToken(userId : String , callback:(String)->Unit) fun getUserName(token : String , callback:(String)->Unit) fun sendMessage(message : String , callback:(String)->Unit)
  • 9. fun test(userId:String, callback:()->Unit){ getToken(userId) token-> { getUserName(token) userName->{ sendMessage("User id is $userId and name is $userName"){ callback.invoke() } } } } fun getToken(userId : String , callback:(String)->Unit) fun getUserName(token : String , callback:(String)->Unit) fun sendMessage(message : String , callback:(String)->Unit) Callback hell
  • 10. fun test(userId:String, callback:()->Unit){ getToken(userId) token-> { getUserName(token) userName->{ sendMessage("User id is $userId and name is $userName"){ callback.invoke() } } } } fun getToken(userId : String) : Single<String> fun getUserName(token : String) : Single<String> fun sendMessage(message : String)
  • 11. fun test(userId:String){ getToken(userId) .flatMap { return@flatMap getUserName(it) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ sendMessage("User id is $userId and name is $userName") }, { //error handling }) }
  • 12. fun sendMessage(userId:String){ getToken(userId) .flatMap { return@flatMap getUserName(it) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ sendMessage("User id is $userId and name is $userName") }, { //error handling }) }
  • 13. fun test(userId:String){ getToken(userId) .flatMap { return@flatMap getUserName(it) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ sendMessage("User id is $userId and name is $userName") }, { //error handling }) }
  • 14. fun sendMessage(userId:String){ 1. val token = getToken(userId) 2. val userName = getUserName(token) 3. sendMessage("User id is $userId and name is $userName") } What we want Sequential
  • 15. Suspend suspend fun getToken(userId : String) : String suspend fun getUserName(token : String) : String suspend fun sendMessage(message : String) : String suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") }
  • 16. suspend fun getToken(userId : String) : String { // do request & suspend return token } suspend fun getUserName(token : String) : String suspend fun sendMessage(message : String) : String suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName")
  • 17. suspend fun getToken(userId : String) : String suspend fun getUserName(token : String) : String suspend fun sendMessage(message : String) suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") } Like Regular code !!
  • 18. suspend fun getToken(userId : String) : String suspend fun getUserName(token : String) : String suspend fun sendMessage(message : String) suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") } Like Regular code !!
  • 19.
  • 20. How does it work ??
  • 22. suspend fun getToken(userId : String) : String public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object fun getToken(userId : String) : String public final getToken(Ljava/lang/String;)Ljava/lang/String; befroe
  • 23. suspend fun getToken(userId : String) : String public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object fun getToken(userId : String) : String public final getToken(Ljava/lang/String;)Ljava/lang/String; Kotlin bytecode for jvm
  • 24. suspend fun getToken(userId : String) : String public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object fun getToken(userId : String) : String public final getToken(Ljava/lang/String;)Ljava/lang/String; After
  • 25. suspend fun getToken(userId : String) : String public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object fun getToken(userId : String) : String public final getToken(Ljava/lang/String;)Ljava/lang/String; After
  • 26. suspend fun getToken(userId : String) : String public final getToken(Ljava/lang/String;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object fun getToken(userId : String) : String public final getToken(Ljava/lang/String;)Ljava/lang/String;
  • 27. Continuation-passing style In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation fun test( ){ val token = requestToken() val userId = getUserId(token) } fun test( ){ getToken { token-> val userId = getUserId(token) } } Direct Style
  • 28. Continuation-passing style In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation fun test( ){ val token = requestToken() val userId = getUserId(token) } fun test( ){ getToken { token-> val userId = getUserId(token) } } Direct Style Continuation
  • 29. Continuation-passing style In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation fun test( ){ val token = requestToken() val userId = getUserId(token) } fun test( ){ getToken { token-> val userId = getUserId(token) } }
  • 30. Continuation-passing style In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation fun test( ){ val token = requestToken() val userId = getUserId(token) } fun test( ){ getToken { token-> val userId = getUserId(token) } } CPS == Callback
  • 31. How does it work interface Continuation<in T> { val context: CoroutineContext fun resume(value: T) fun resumeWithException(exception: Throwable) }
  • 32. class test(userId:String , sm : Continuation<Unit>) : Any{ val sm = CoroutineImpl { fun doResume(...){ test(null,this) } var token : String var userName : String } switch(sm.Label){ case 0: sm.Label = 1 getToken(userId,sm) break case 1: sm.Label = 2 getUserName(sm.token , sm) break case 2: sm.Label = 3 sendMessage("User id is $userId and name is $userName") break } } suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") }
  • 33. class test(userId:String , callback : Continuation<Unit>) : Any{ val sm = CoroutineImpl { fun resume(...){ test(null,this) } var token : String var userName : String } switch(sm.Label){ case 0: sm.Label = 1 getToken(userId,sm) break case 1: sm.Label = 2 getUserName(sm.token , sm) break case 2: sm.Label = 3 sendMessage("User id is $userId and name is $userName") break } } suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") }
  • 34. class test(userId:String , callback : Continuation<Unit>) : Any{ val sm = CoroutineImpl { fun doResume(...){ test(null,this) } var token : String var userName : String } switch(sm.Label){ case 0: sm.Label = 1 getToken(userId,sm) break case 1: sm.Label = 2 getUserName(sm.token , sm) break case 2: sm.Label = 3 sendMessage("User id is $userId and name is $userName") break } } suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") }
  • 35. class test(userId:String , callback : Continuation<Unit>) : Any{ val sm = CoroutineImpl { fun doResume(...){ test(null,this) } var token : String var userName : String } switch(sm.Label){ case 0: sm.Label = 1 getToken(userId,sm) break case 1: sm.Label = 2 getUserName(sm.token , sm) break case 2: sm.Label = 3 sendMessage("User id is $userId and name is $userName") break } } suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") } spending function
  • 36. class test(userId:String , callback : Continuation<Unit>) : Any{ val sm = CoroutineImpl { fun doResume(...){ test(null,this) } var token : String var userName : String } switch(sm.Label){ case 0: sm.Label = 1 getToken(userId, sm ) break case 1: sm.Label = 2 getUserName(sm.token , sm) break case 2: sm.Label = 3 sendMessage("User id is $userId and name is $userName") break } } suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") } Restore state
  • 37. class test(userId:String , callback : Continuation<Unit>) : Any{ val sm = CoroutineImpl { fun resume(...){ test(null,this) } var token : String var userName : String } switch(sm.Label){ case 0: sm.Label = 1 getToken(userId,sm) break case 1: sm.Label = 2 getUserName(sm.token , sm) break case 2: sm.Label = 3 sendMessage("User id is $userId and name is $userName") break } } suspend fun test(userId:String){ val token = getToken(userId) val userName = getUserName(token) sendMessage("User id is $userId and name is $userName") }
  • 39. Retrofit kotlin version 1.3 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' kotlin version pre-1.3 implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0' val retrofit = Retrofit.Builder() .baseUrl("https://example.com/") .addCallAdapterFactory(CoroutineCallAdapterFactory()) .build()
  • 42. Retrofit GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser() withContext(Dispatchers.Main) { showMesssgae(data.await().message) } }
  • 44. Retrofit suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont -> cont.invokeOnCancellation { if (cont.isCancelled) { cont.cancel() } } enqueue(object : Callback<T> { override fun onFailure(call: Call<T>?, t: Throwable) { cont.resumeWithException(t) } override fun onResponse(call: Call<T>?, response: Response<T>) { if (response.isSuccessful) { val body = response.body() ?: return cont.resumeWithException(NullPointerException()) cont.resume(body) } else { cont.resumeWithException(HttpException(response)) } } }) }
  • 45. Retrofit suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont -> cont.invokeOnCancellation { if (cont.isCancelled) { cont.cancel() } } enqueue(object : Callback<T> { override fun onFailure(call: Call<T>?, t: Throwable) { cont.resumeWithException(t) } override fun onResponse(call: Call<T>?, response: Response<T>) { if (response.isSuccessful) { val body = response.body() ?: return cont.resumeWithException(NullPointerException()) cont.resume(body) } else { cont.resumeWithException(HttpException(response)) } } }) }
  • 46. Retrofit GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser().await() withContext(Dispatchers.Main) { showMesssgae(data.message) } }
  • 47. Retrofit GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser().await() withContext(Dispatchers.Main) { showMesssgae(data.message) } } // Call<T>.await is extension function retrun data
  • 48. Error handling GlobalScope.launch(Dispatchers.IO) { try { val data = APIRepo.getUser() withContext(Dispatchers.Main) { showMesssgae(data.message) } }catch(e : Exception){ // error } }
  • 49. How to cancel ? val job = GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser() withContext(Dispatchers.Main) { showMesssgae(data.message) } } job.cancel() // RxJava Disposable
  • 50. How to cancel ? job.cancel()
  • 51. Job Job 

.. n class MainActivityTest : AppCompatActivity(), CoroutineScope { private val job = Job() override val coroutineContext: CoroutineContext get() = job + Dispatchers.Main override fun onDestroy() { super.onDestroy() job.cancel() } GlobalScope.launch(coroutineContext) { //do async } GlobalScope.launch(coroutineContext) { //do async } GlobalScope.launch(coroutineContext) { //do async }
  • 52. Concurrently GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser() // Deferred withContext(Dispatchers.Main) { showMesssgae(data.await().message) } }
  • 53. Concurrently GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser() // Deferred val dataNew = APIRepo.getUserNew() // Deferred val dataNewTwo = APIRepo.getUserNewTwo() // Deferred withContext(Dispatchers.Main) { showMesssgae(data.await().message) } }
  • 54. Concurrently GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser() // Deferred val dataNew = APIRepo.getUserNew() // Deferred val dataNewTwo = APIRepo.getUserNewTwo() // Deferred withContext(Dispatchers.Main) { showMesssgae(data.await().message) } }
  • 55. Concurrently GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser() // Deferred val dataNew = APIRepo.getUserNew() // Deferred val dataNewTwo = APIRepo.getUserNewTwo() // Deferred withContext(Dispatchers.Main) { showMesssgae(data.await().message,dataNew.await().message,dataNewTwo.await().message) } }
  • 58. GlobalScope.launch(Dispatchers.IO) { val data = APIRepo.getUser() // Deferred withContext(Dispatchers.Main) { showMesssgae(data.await().message) } }
  • 59.
  • 60. Recap ● Asynchronous ● Apk Siz & Method count ● Performance ● Readable ● Cost
  • 61. Recap ● Asynchronous ● Apk size & Method count ● Performance ● Readable ● Cost
  • 62. Recap ● Asynchronous ● Apk Siz & Method count ● Performance ● Readable ● Cost
  • 63. Recap ● Asynchronous ● Apk Siz & Method count ● Performance ● Readable ● Cost
  • 64. Recap ● Asynchronous ● Apk Siz & Method count ● Performance ● Readable ● Cost
  • 65. Q & A Thank you

Hinweis der Redaktion

  1. 戆äș«è‡Ș深慄門的經驗 why coroountines ? What’s the goal ? What’s the problem want fix ? Reduce apk size Both method count & size smaller 10~20% than RxJava èŒ•é‡ćŒ–çš„Thread ćœšç·šçąŒéšŽæź”ćšćˆ°Thread的management ćŻ«ćŒæ­„çš„Codeć»ćŻä»„èź“äœ è™•ç†ç•°æ­„çš„äș‹æƒ… 曠ç‚șçœ‹ćˆ°æœ€èż‘çš„æ–‡ç« ćœ±ç‰‡éƒœćœšèȘȘé—œæ–Œé€™ć€‹æŠ‚ćż”çš„æ±è„ż,ć› è€Œé–‹ć§‹äœżç”š
  2. æˆ‘ć€‘éƒœçŸ„é“ćœšäž€ć€‹æ‡‰ç”šçš‹ćŒçš„é–‹ć§‹,Android甊äșˆé€™ć€‹process侀怋Thread甚斌æžČæŸ“ç•«éą, æ‰€ä»„ćŠ‚æžœä»Šć€© ć‡ș珟äș†äž€äș›ć·„䜜 æœƒæ¶äœ”é€™ć€‹ThreadBlocking thread 打äș‚æœŹäŸ†ćœšćšæžČ染threadçš„æ­„èȘżçš„æ™‚ć€™. æˆ‘ć€‘ćż…é ˆèŠćœšèȘżç”šæ–°çš„worker thread äčŸć°±æ˜Żæ‰€èŹ‚çš„Asynchronousçš„æŠ‚ćż”
  3. è§Łé‡‹ćŒæ­„ç•°æ­„çš„ć·źç•° 針氍Async的處理, android 柘æ–čäčŸæäŸ›äž€äș›ćș«,äčŸæœ‰äș›æš™æș–çš„äœœæł•
  4. è§Łé‡‹é€™æ˜Żäž€ć€‹step by step 的simple case It just a simple code , concept
  5. Every step is depend on last stept 盾äș’äŸèłŽ getToken ć‡èš­ç”ŠäșˆuserIdćŻä»„æ‹żćˆ°token getUserName inpu token can get user name Last step is just print the userid & usaname
  6. But what if the case going to a liitl bit different When getToken this method need to create new thread witch mean workThread to do async also the getUserName need it too The last step also print message
  7. The first way in my mind is using callback ,
  8. ćŠ‚æžœæˆ‘æƒłèŠæˆ‘çš„codeć°±ćŻèź€æ€§è€Œèš€,ä»–ć°±èŠćƒdirct code äž€æšŁ 1 2 3 䟝ćșćźŒæˆ
  9. 驖慈看戰Test fun ćœšç·šçąŒéšŽæź” 由生Countinuation 的 input callback æČ’æœ‰ć•éĄŒ
  10. ć†äŸ† sm ä»ŁèĄšè‘— Countinuationçš„ćŻŠäŸ‹ , èŁĄéąćŒ…ć« resume() ä»„ćŠç”ąç”Ÿ 這怋fun慧 會有的token & username çš„ćƒæ•ž
  11. æœ€ćŸŒć°±æ˜Żćˆ°ćș•æ€ŽéșŒé‹èĄŒçš„
  12. 跟callbackçš„ć·źćˆ„
  13. é€™ćŻèƒœäčŸæ˜Żć€§ćź¶é—œæłšçš„è­°éĄŒäč‹äž€ Why should i need this What’s new about performance in Kotlin coroutines
  14. Dispatchers æ˜ŻćŻä»„æŒ‡ćźš IO Main Executes
  15. ć°æ–ŒDefalutä»–èƒŒćŸŒçš„ćŻŠèžæ˜ŻForJoin pool
  16. Why coroutines? Async task RxJava Call back Thread Thread Pool
  17. If you guys consider about Apk szie & method count 10% ~ 20% reduce apk size
  18. ćŠ‚æžœæŻäž€æŹĄçš„Asyncć°±è”·äž€ć€‹Thread æ‰€ä»„ćŻèƒœæœƒç”šThread pool or AsyncTask ćŠ‚æžœæƒłèŠćœšcode的敎體甐構 曎枅愚明瞭 䞍æŠčæźșæŽ‰ćˆ‡æ›Threadçš„äœœæł•ç•¶ç„¶æ˜ŻRxJava äœ†ćŠ‚æžœć°±corountines dispatcher的觀點看,ä»–èƒŒćŸŒäčŸæŒ‡ç€șæŒ‡ć‘äž€ć€‹Thread pool ćȘäžéŽä»–æ˜ŻForJoinPoolć°æ–Œć€šć€‹Taskçš„æŒ‡æŽŸćŻä»„æ›Žæœ‰æ•ˆçŽ‡çš„ćźŒæˆ , 䜠äčŸćŻä»„è”·äž€ć€‹ForJoinPooläžäœżç”šcoroutines的frameworkćŽ»è™•ç†task äœ†ć°±callback hell的觀點 äč‹ć‰äčŸæćˆ° 侀怋coroutines的scope郜ćȘæœƒć…±ç”šäž€ć€‹continution , ç›žèŒƒæ–Œć€šć€‹callback的曞悳 民äș†äžć°‘objectć°æ–Œçł»ç”±çš„èČ æ“”
  19. ćŠ‚æžœæŻäž€æŹĄçš„Asyncć°±è”·äž€ć€‹Thread æ‰€ä»„ćŻèƒœæœƒç”šThread pool or AsyncTask ćŠ‚æžœæƒłèŠćœšcode的敎體甐構 曎枅愚明瞭 䞍æŠčæźșæŽ‰ćˆ‡æ›Threadçš„äœœæł•ç•¶ç„¶æ˜ŻRxJava äœ†ćŠ‚æžœć°±corountines dispatcher的觀點看,ä»–èƒŒćŸŒäčŸæŒ‡ç€șæŒ‡ć‘äž€ć€‹Thread pool ćȘäžéŽä»–æ˜ŻForJoinPoolć°æ–Œć€šć€‹Taskçš„æŒ‡æŽŸćŻä»„æ›Žæœ‰æ•ˆçŽ‡çš„ćźŒæˆ , 䜠äčŸćŻä»„è”·äž€ć€‹ForJoinPooläžäœżç”šcoroutines的frameworkćŽ»è™•ç†task äœ†ć°±callback hell的觀點 äč‹ć‰äčŸæćˆ° 侀怋coroutines的scope郜ćȘæœƒć…±ç”šäž€ć€‹continution , ç›žèŒƒæ–Œć€šć€‹callback的曞悳 民äș†äžć°‘objectć°æ–Œçł»ç”±çš„èČ æ“”