package Ġcom . big v and . surf board . utils Ċ Ċ import Ġandroidx . annotation . MainThread Ċ import Ġandroidx . annotation . Worker Thread Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Mediator LiveData Ċ import Ġcom . big v and . surf board . models . ResponseError Body Ċ import Ġkotlinx . coroutines .* Ċ import Ġretrofit 2 . Call Ċ import Ġretrofit 2 . Callback Ċ import Ġretrofit 2 . Response Ċ import Ġjava . io . IOException Ċ Ċ /** Ċ Ġ* ĠA Ġgeneric Ġclass Ġthat Ġcan Ġprovide Ġa Ġresource Ġbacked Ġby Ġboth Ġthe Ġsqlite Ġdatabase Ġand Ġthe Ġnetwork . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠYou Ġcan Ġread Ġmore Ġabout Ġit Ġin Ġthe Ġ[ Architecture Ċ Ġ* ĠGuide ]( https :// developer . android . com / arch ). Ċ Ġ* Ġ@ param Ġ< Result Type > Ċ Ġ* Ġ@ param Ġ< RequestType > Ċ </ RequestType ></ Result Type > Ġ*/ Ċ @ Suppress (" Le aking This ") Ċ abstract Ġclass ĠNetwork Bound Resource < ApiResponse Type , ĠData BaseModel Type > Ċ @ MainThread Ġconstructor (/* private Ġval Ġapp Executors : ĠApp Executors */) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġm Job 1 Ġ= ĠJob () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġm Job 2 Ġ= ĠJob () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġm Io Coroutine Ġ= ĠCor outine Scope ( Dispatch ers . IO Ġ+ Ġm Job 1 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġm Cpu Coroutine Ġ= ĠCor outine Scope ( Dispatch ers . Default Ġ+ Ġm Job 2 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġm Api InProgress Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġval Ġresult Ġ= ĠMed iator LiveData < Resource < Data BaseModel Type >>() ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdb Source Ġ= Ġload From Db () ĊĠĠĠĠĠĠĠ ĠsetValue ( Resource . loading ( null )) ĊĠĠĠĠĠĠĠ Ġresult . add Source ( db Source ) Ġ{ Ġdata Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( Resource . success ( data , Ġ 2 0 0 )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Io Coroutine . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfetch From Network () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprivate Ġfun ĠsetValue ( newValue : ĠResource < Data BaseModel Type >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( result . value Ġ!= ĠnewValue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . post Value ( newValue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch From Network () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcall Ġ= Ġcreate Call () ĊĠĠĠĠĠĠĠ Ġcall . enqueue ( object Ġ: ĠCallback < ApiResponse Type > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Failure ( call : ĠCall < ApiResponse Type >, Ġt : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResource . error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠApp Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse Error Body (" 8 0 0 ", Ġ" Android Ġmodel Ġerror ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ), Ġnull , Ġ 8 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Response ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcall : ĠCall < ApiResponse Type >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse : ĠResponse < ApiResponse Type > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . is Successful Ġ&& Ġresponse . code () Ġin Ġ 2 0 0 .. 2 9 9 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . body ()?. let Ġ{ Ġapi Response Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Io Coroutine . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( m Cpu Coroutine . coroutine Context ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconvert Response ( api Response )?. let Ġ{ Ġnew Response Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Call Result ( new Response ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġlet Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Call Result ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġlet Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Call Result ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Ġ= ĠIOException ( response . message ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Body Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse Error Body ( response . code (). toString (), Ġresponse . message ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResource . error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠApp Exception ( error , Ġerror Body ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . code () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġopen Ġfun Ġon Fetch Failed () Ġ{} ĊĊĠĠĠ Ġpublic Ġval Ġas LiveData : ĠLive Data < Resource < Data BaseModel Type >> Ġ= Ġresult ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġsave Call Result ( item : ĠData BaseModel Type ?) ĊĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġload From Db (): ĠLive Data < Data BaseModel Type > ĊĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġcreate Call (): ĠCall < ApiResponse Type > ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġconvert Response ( api Response : ĠApi ResponseType ): ĠData BaseModel Type ? Ċ }