// ĠCreated Ġby Ġ è¶ħ æĤ Ł ç©º Ġon Ġ 2 0 2 1 / 4 / 8 . Ċ Ċ package Ġorg . cw k . work Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġokhttp 3 . Call Ċ import Ġokhttp 3 . Callback Ċ import Ġokhttp 3 . Response Ċ import Ġjava . io . IOException Ċ import Ġkotlin . coroutines . Coroutine Context Ċ import Ġkotlin . coroutines . resume Ċ import Ġkotlin . coroutines . resume With Exception Ċ Ċ /** Ċ Ġ* Ġ ä»»åĬ¡ Ċ Ġ* Ċ Ġ* Ġåı¯ä»¥ åĲ¯åĬ¨ ç½ĳç»ľ è¯·æ±Ĥ Ċ Ġ* Ġ ä»»åĬ¡ æµģç¨ĭ ä¾Ŀèµĸ åįı ç¨ĭ å®ŀçİ° ï¼Į åĲĮ æł· éģ µ å¾ª éĢļè¿ĩ åįı ç¨ĭ åıĸæ¶Ī ä»»åĬ¡ Ċ Ġ* Ċ Ġ* Ġ æīĢæľī æĸ¹æ³ķ é»ĺè®¤ åľ¨ [ Dispatch ers . IO ] ä¸Ń æī§è¡Į ï¼Į åı¯ éĢļè¿ĩ [ execute ] åıĤæķ° æĶ¹åıĺ åįı ç¨ĭ ä¸Ĭä¸ĭ æĸĩ Ċ Ġ* Ċ Ġ* ĠæŃ¤ ç±» ä¸º ä»»åĬ¡ åŁºç¡Ģ æ¨¡æĿ¿ ï¼Į éľĢè¦ģ çĶ¨æĪ· åľ¨ é¡¹çĽ® ä¸Ń æł¹æį® å®ŀéĻħ çļĦ ä¸ļåĬ¡ http éĢļ çĶ¨ åįıè®® å®ŀçİ° èĩªå·±çļĦ åŁº ç±» å¹¶ è¿Ľ ä¸ĢæŃ¥ ç»§æī¿ å®ŀçİ° åĲĦ ä¸ª æİ¥åı£ [ Work ] Ċ Ġ* Ċ Ġ* Ġ@ param ĠD Ġ åħ³èģĶ çļĦ [ Work ] å®ŀéĻħ è¿ĶåĽŀ çļĦ [ Work Data . result ] ç»ĵæŀľ æķ°æį® ç±»åŀĭ Ċ Ġ* Ġ@ param ĠT Ġ[ Work ] è¿ĶåĽŀ çļĦ ç»ĵæŀľ åĮħ è£ħ ç±»åŀĭ [ Work Data ] Ċ Ġ* Ġ@ param ĠH Ġå¯¹ [ okhttp 3 . Ok HttpClient ] åĵįåºĶ æķ°æį®çļĦ ä¸ŃéĹ´ è½¬æį¢ ç±»åŀĭ ï¼Į éĢļå¸¸ çĶ± çĶ¨æĪ· æł¹æį® é¡¹çĽ® å®ŀéĻħ æĥħåĨµ èĩª è¡Į å®ļ åĪ¶ å®ŀçİ° è½¬æį¢ ï¼Į åıĤ è§ģ [ on Response Convert ] Ċ Ġ*/ Ċ abstract Ġclass ĠWork < D , ĠT Ġ: ĠWork Data < D >, ĠH > Ġ: ĠWork Core < D , ĠT , ĠH >() Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ æĹ¥å¿Ĺ æłĩçŃ¾ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Transient ĊĠĠĠ Ġprivate Ġval Ġ_ tag Ġ= Ġ"${ java Class . simple Name }@ ${ this . hashCode (). toString ( 1 6 )}" ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġexecute ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠCor outine Context , ĊĠĠĠĠĠĠĠ Ġretry : ĠInt , ĊĠĠĠĠĠĠĠ Ġon Send Progress : ĠOn Progress ?, ĊĠĠĠĠĠĠĠ Ġon Receive Progress : ĠOn Progress ? ĊĠĠĠ Ġ): ĠT Ġ= Ġwith Context ( context Ġ+ ĠCor outine Name (_ tag )) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog V (_ tag , Ġ" work Ġexecute ") ĊĠĠĠĠĠĠĠ ĠonCreate Work Data (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonStart Work ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( from Cache ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ apply ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions Ġ= ĠonCreate Options ( retry , Ġon Send Progress , Ġon Receive Progress ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Do Work ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog V (_ tag , Ġ" on Successful ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Successful ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e Ġis ĠC ancellation Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror Type Ġ= ĠWork ErrorType . CANCEL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog W (_ tag , Ġ" on Canceled ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Canceled ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror Type Ġ= Ġif Ġ( e Ġis ĠWork Exception ) Ġe . type Ġelse ĠWork ErrorType . OTHER ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġe . message ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog W (_ tag , Ġ" on Failed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Failed ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog V (_ tag , Ġ" on Finished ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Finished ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog V (_ tag , Ġ" work Ġfinished ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ ä»»åĬ¡ åĲ¯åĬ¨ åīį ç½® æĸ¹æ³ķ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun ĠonStart Work ( data : ĠT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! on Check Params ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" on Params Error ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠWork Exception ( Work ErrorType . PARAMS , Ġon Params Error ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġdata . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġon Started ( this ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ!= Ġnull Ġ&& Ġresult Ġ!= ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom Cache Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġon From Cache Message ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ æŀĦå»º è¯·æ±Ĥ éĢīé¡¹ åıĤæķ° ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun ĠonCreate Options ( ĊĠĠĠĠĠĠĠ Ġretry : ĠInt , ĊĠĠĠĠĠĠĠ Ġon Send Progress : ĠOn Progress ?, ĊĠĠĠĠĠĠĠ Ġon Receive Progress : ĠOn Progress ? ĊĠĠĠ Ġ): ĠOptions Ġ= ĠOptions ( ĊĠĠĠĠĠĠĠ Ġurl Ġ= Ġurl (), ĊĠĠĠĠĠĠĠ Ġparams Ġ= Ġfill Params (), ĊĠĠĠĠĠĠĠ Ġmethod Ġ= Ġhttp Method (), ĊĠĠĠĠĠĠĠ Ġretry Ġ= Ġretry , ĊĠĠĠĠĠĠĠ Ġconfig Key Ġ= Ġconfig Key (), ĊĠĠĠĠĠĠĠ Ġheaders Ġ= Ġheaders (), ĊĠĠĠĠĠĠĠ ĠcontentType Ġ= ĠcontentType (), ĊĠĠĠĠĠĠĠ Ġon Send Progress Ġ= Ġon Send Progress , ĊĠĠĠĠĠĠĠ Ġon Receive Progress Ġ= Ġon Receive Progress , ĊĠĠĠ Ġ). apply Ġ{ Ġon Post Options ( this ) Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠæŃ¤ å¤Ħ ä¸º çľŁ æŃ£ åĲ¯åĬ¨ http è¯·æ±Ĥ çļĦæĸ¹æ³ķ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Do Work ( data : ĠT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog I (_ tag , Ġ" request ", Ġdata . options ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwork Request ( data . options !! ) (_ tag , Ġdata . options !! ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" on Params Error ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠWork Exception ( Work ErrorType . PARAMS , Ġon Params Error (), Ġe ) ĊĠĠĠĠĠĠĠ Ġ}. let Ġ{ Ġcall Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog I (_ tag , Ġ" real Ġurl ", Ġcall . request (). url ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Call ( data , Ġcall ). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Handle Response ( data , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġæī§è¡Į ç½ĳç»ľ è¯·æ±Ĥ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Call ( data : ĠT , Ġcall : ĠCall ): ĠResponse Ġ= Ġsuspend C ancellable Coroutine Ġ{ ĊĠĠĠĠĠĠĠ Ġit . invoke On Cancellation Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" http Ġcancelled ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcall . cancel () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcall . enqueue ( object Ġ: ĠCallback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Response ( call : ĠCall , Ġresponse : ĠResponse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . resume ( response ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Failure ( call : ĠCall , Ġe : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . is Cancelled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" on Network Error ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . resume With Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWork Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e . message Ġ== Ġ" timeout ") ĠWork ErrorType . TIMEOUT Ġelse ĠWork ErrorType . NETWORK , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Network Error ( data ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ å¤ĦçĲĨ åĵįåºĶ ç»ĵæŀľ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Handle Response ( data : ĠT , Ġresponse : ĠResponse ) Ġ= Ġdata . apply Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . response Ġ= ĠHttpResponse ( response . is Successful , Ġresponse . code , Ġresponse . headers ) ĊĠĠĠĠĠĠĠ Ġlog I (_ tag , Ġ" response ", Ġthis . response ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( response . is Successful ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog V (_ tag , Ġ" on Response Convert ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Parse ( this , Ġon Response Convert ( this , Ġresponse . body !! )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e Ġ! is ĠC ancellation Exception Ġ&& Ġe Ġ! is ĠWork Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" on Parse Failed ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠWork Exception ( Work ErrorType . PARSE , Ġon Parse Failed ( this ), Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" on Network Request Failed ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠWork Exception ( Work ErrorType . RESPONSE , Ġon Network Request Failed ( this )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ è§£æŀĲ åĵįåºĶ ä½ĵ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġon Parse ( data : ĠT , Ġbody : ĠH ) Ġ= Ġdata . apply Ġ{ ĊĠĠĠĠĠĠĠ Ġlog I (_ tag , Ġ" body ", Ġbody ) ĊĊĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġon Request Result ( data , Ġbody ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog V (_ tag , Ġ" on Request Success ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġon Request Successful ( data , Ġbody ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog V (_ tag , Ġ" on Request Success Message ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġon Request Successful Message ( data , Ġbody ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" on Request Failed ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġon Request Failed ( data , Ġbody ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (_ tag , Ġ" on Request Failed Message ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠWork Exception ( Work ErrorType . TASK , Ġon Request Failed Message ( data , Ġbody )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }