package Ġcom . example . b ache lor pro ef . view model Ċ Ċ import Ġandroid . app . Application Ċ import Ġandroid . util . Log Ċ import Ġandroidx . lifecycle .* Ċ import Ġcom . example . b ache lor pro ef . R Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . channels . Receive Channel Ċ import Ġjava . lang . Index OutOfBoundsException Ċ Ċ class ĠAsync ViewModel ( application : ĠApplication ) Ġ: ĠAndroid ViewModel ( application ){ ĊĠĠĠ Ġprivate Ġval Ġis Coroutine Loading Ġ= ĠMutable LiveData ( false ) ĊĠĠĠ Ġprivate Ġval Ġis Channel Loading Ġ= ĠMutable LiveData ( false ) ĊĊĠĠĠ Ġprivate Ġval Ġcoroutine Error String Ġ= Ġapplication . getString ( R . string . coroutine _ error ) ĊĠĠĠ Ġprivate Ġval Ġcoroutine Idle String Ġ= Ġapplication . getString ( R . string . coroutine _ idle ) ĊĠĠĠ Ġprivate Ġval Ġcoroutine Done String Ġ= Ġapplication . getString ( R . string . coroutine _ done ) ĊĠĠĠ Ġprivate Ġval Ġchannel Error String Ġ= Ġapplication . getString ( R . string . channel _ error ) ĊĠĠĠ Ġprivate Ġval Ġchannel Idle String Ġ= Ġapplication . getString ( R . string . channel _ idle ) ĊĠĠĠ Ġprivate Ġval Ġcoroutine Output Ġ= ĠMutable LiveData ( coroutine Idle String ) ĊĠĠĠ Ġprivate Ġval Ġchannel Output Ġ= ĠMutable LiveData ( channel Idle String ) ĊĊĠĠĠ Ġprivate Ġvar Ġcoroutine Executed Ġ= ĠMutable LiveData ( false ) ĊĠĠĠ Ġprivate Ġvar Ġchannel Executed Ġ= ĠMutable LiveData ( false ) ĊĊĠĠĠ Ġfun Ġget Coroutine Output () Ġ: ĠLive Data < String > Ġ= Ġcoroutine Output ĊĠĠĠ Ġfun Ġget Channel Output () Ġ: ĠLive Data < String > Ġ= Ġchannel Output ĊĠĠĠ Ġfun Ġget Is Coroutine Loading () Ġ: ĠLive Data < Boolean > Ġ= Ġis Coroutine Loading ĊĠĠĠ Ġfun Ġget Is Channel Loading () Ġ: ĠLive Data < Boolean > Ġ= Ġis Channel Loading ĊĊĠĠĠ Ġsuspend Ġfun Ġon Coroutine () Ġ: ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġdelay ( 3 0 0 L )// P ret end Ġwe Ġdo Ġsomething , Ġnot Ġcounted Ġin Ġresults Ġsince Ġit 's Ġa Ġ' fake ' Ġcoroutine ĊĠĠĠĠĠĠĠ Ġreturn Ġcoroutine Done String ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġon Coroutine WithError () Ġ: ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġdelay ( 3 0 0 L )// P ret end Ġwe Ġdo Ġsomething ĊĠĠĠĠĠĠĠ Ġthrow ĠIndex OutOfBoundsException (" O ops !") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġstart Channel ( channel : ĠChannel < Int > ){ ĊĠĠĠĠĠĠĠ Ġfor Ġ( x Ġin Ġ 1 .. 5 ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 2 0 0 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . send ( x Ġ* Ġx ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġchannel . close () // Ġwe 're Ġdone Ġsending ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġreceive From Channel ( channel : ĠChannel < Int > ){ ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġchannel ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel Output . value Ġ= Ġi . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġchannel Executed . value Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdo Coroutine (){ ĊĠĠĠĠĠĠĠ Ġif ( coroutine Executed . value !! ) Ġreturn ĊĠĠĠĠĠĠĠ Ġcoroutine Executed . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Coroutine Loading . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Output . value Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Output . value Ġ= Ġon Coroutine () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Coroutine Loading . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Executed . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdo Coroutine WithError (){ ĊĠĠĠĠĠĠĠ Ġif ( coroutine Executed . value !! ) Ġreturn ĊĠĠĠĠĠĠĠ Ġcoroutine Executed . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Coroutine Loading . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Output . value Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Output . value Ġ= Ġon Coroutine WithError () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} catch Ġ( ex Ġ: ĠIndex OutOfBoundsException ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Output . value Ġ= Ġcoroutine Error String ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} finally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Coroutine Loading . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Executed . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdo Channel (){ ĊĠĠĠĠĠĠĠ Ġif ( channel Executed . value !! ) Ġreturn ĊĠĠĠĠĠĠĠ Ġchannel Executed . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= ĠChannel < Int >() ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Channel ( channel ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreceive From Channel ( channel ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġstart Error Channel ( channel Ġ: ĠChannel < Int > ){ ĊĠĠĠĠĠĠĠ Ġtry { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( x Ġin Ġ 1 .. 5 ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Channel Loading . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 2 0 0 L ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( x Ġ== Ġ 3 ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIndex OutOfBoundsException (" O ops !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} else { ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . send ( x Ġ* Ġx ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Channel Loading . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} catch Ġ( e Ġ: ĠIndex OutOfBoundsException ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel Output . value Ġ= Ġchannel Error String ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Channel Loading . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} finally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġreceive From Error Channel ( channel : ĠChannel < Int > ){ ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġchannel ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel Output . value Ġ= Ġi . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Experimental Cor outines Api ĊĠĠĠ Ġfun Ġdo Channel WithError (){ ĊĠĠĠĠĠĠĠ Ġif ( channel Executed . value !! ) Ġreturn ĊĠĠĠĠĠĠĠ Ġchannel Executed . value Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= ĠChannel < Int >() ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Error Channel ( channel ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreceive From Error Channel ( channel ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ }