package Ġcom . l uk as le ch ner . coroutine use case son android . use cases . coroutines . use case 1 1 Ċ Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġkotlinx . coroutines .* Ċ import Ġjava . math . BigInteger Ċ import Ġkotlin . system . measure Time Millis Ċ Ċ class ĠC ooper ative Cancellation ViewModel ( ĊĠĠĠ Ġprivate Ġval Ġdefault Dispatcher : ĠCor outine Dispatcher Ġ= ĠDispatch ers . Default Ċ ) Ġ: ĠViewModel () Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġcalculation Job : ĠJob ? Ġ= Ġnull ĊĊĠĠĠ Ġfun Ġperform Calculation ( factor ial Of : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġui State . value Ġ= ĠUi State . Loading ĊĠĠĠĠĠĠĠ Ġcalculation Job Ġ= ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġresult : ĠBigInteger Ġ= ĠBigInteger . ZERO ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcomputation Duration Ġ= Ġmeasure Time Millis Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġcalculate Factor ial Of ( factor ial Of ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġresult String Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstring Conversion Duration Ġ= Ġmeasure Time Millis Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult String Ġ= Ġconvert ToString ( result ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui State . value Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUi State . Success ( result String , Ġcomputation Duration , Ġstring Conversion Duration ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui State . value Ġ= Ġif Ġ( exception Ġis ĠC ancellation Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUi State . Error (" Calculation Ġwas Ġcancelled ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUi State . Error (" Error Ġwhile Ġcalculating Ġresult ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġfactor ial Ġof Ġn Ġ( n !) Ġ= Ġ 1 Ġ* Ġ 2 Ġ* Ġ 3 Ġ* Ġ 4 Ġ* Ġ... Ġ* Ġn ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġcalculate Factor ial Of ( number : ĠInt ): ĠBigInteger Ġ= ĊĠĠĠĠĠĠĠ Ġwith Context ( default Dispatcher ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġfactor ial Ġ= ĠBigInteger . ONE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. number ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġyield Ġenables Ġc ooper ative Ġcancell ations ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġalternatives : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ- Ġensure Active () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ- ĠisActive () Ġ- Ġpossible Ġto Ġdo Ġclean Ġup Ġtasks Ġwith ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġyield () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfactor ial Ġ= Ġfactor ial . multiply ( BigInteger . valueOf ( i . to Long ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactor ial ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġconvert ToString ( number : ĠBigInteger ): ĠString Ġ= ĊĠĠĠĠĠĠĠ Ġwith Context ( default Dispatcher ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnumber . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġui State (): ĠLive Data < Ui State > Ġ= Ġui State ĊĊĠĠĠ Ġfun Ġcancel Calculation () Ġ{ ĊĠĠĠĠĠĠĠ Ġcalculation Job ?. cancel () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġui State : ĠMutable LiveData < Ui State > Ġ= ĠMutable LiveData () Ċ }