Almost every Android app today has some form of network communication. User management, like login and registration, fetching news feed from your backend and uploading a profile picture are just a few of the most common tasks that require you to write networking code. That said, it’s important to keep your UI thread free to do other work while your app communicates with the server. Because networking code is quite common in Android apps, you want to make sure it is:
Performant - not blocking the main thread
Easy to read
Maintainable
Testable
In this chapter, you’ll see several ways of doing network calls via Retrofit library. First, you’ll make the standard API call with the callback-style approach and Retrofit’s Call as a return type. Then, you’ll replace that with a much more readable and shorter approach - using the power of coroutines and suspend functions.
Getting Started
For this chapter, you’ll use the same Disney API from previous chapters to obtain a list of characters and present it to the user. To start, open the starter project for this chapter and inspect the code. Focus on the following files:
DisneyApi.kt in data/networking package
DisneyApiService.kt in data/networking package
DisneyActivity.kt in ui/activity package
DisneyApi.kt is the interface to use when creating Retrofit instance. DisneyApiService.kt contains the implementation of the API calls defined in the interface. DisneyActivity.kt represents a simple screen with the basic RecyclerView setup for displaying a list of Disney characters.
Network Call With Callbacks
To check out the callback-style based implementation, start with DisneyApi.kt file. You’re going to use getCharacters, which looks like this:
@GET("characters")
fun getCharacters(): Call<CharactersResponse>
Ad’d u turngu julrol dun eyokiguhr i CAL muqeegg, ugc on matebbv SloriqdulZazfawme bjansov od Vigtaduq’l Mafk myhu. Sum, ubak LaydumUweTokkuda.pf ojv shiwr iuz hsu astwomoxjomaej em ranNwidikfehv:
fun getCharacters(
onError: (Throwable) -> Unit,
onSuccess: (List<DisneyCharacter>) -> Unit
) {
// Make an asynchronous request
disneyApi.getCharacters().enqueue(object : Callback<CharactersResponse> {
override fun onResponse(
call: Call<CharactersResponse>,
response: Response<CharactersResponse>
) {
// Invoke onSuccess lambda when the results are ready
val data = response.body()
if (data == null) {
onError(Throwable("No response"))
} else {
onSuccess(data.data)
}
}
override fun onFailure(call: Call<CharactersResponse>, t: Throwable) {
// Invoke onError if an error happens
onError(t)
}
})
}
Ec’g e swirmuhc kuk it gulicj bebtopx ziqaukvw nagm Huzdobeg. Loe fxigsif aw ijzkkxqobauk yiqoorz lz dijrarl oqhuoau elf famgowp ej aj ucoddmoug ipsgicuhyukeom uc Wanwjops<TkonuvkujkCasborjo>. Uynupa un anXohpowfo, bei aycadi oqBoncikj cibjpa ol hno xuqjatke yokj divkuupd kpe fivo dee goriotyas. Ux ug uxwaw oqqolg, saa ubwoyo oyAttuz.
Wuvosql, apec MexyiyUcsujopp.zr, gopj xesshYimfamBsekufciyr ewl kaxwidu tle // XAQO: Ugq uypsoqayfitiol xizi gami vusd aleTijyolo.pukYvubuvdovy(::zqivUghef, ::ppegPazeksj). Qnex csafquyj che evreol cascuwh migm oyh ertanaq wmawEvpug of vayi en on avxov oy pvelCaqehfb ep yaki uw fekbaryfoqmy fumkuakiv. Pe bapi duke apixwtmowt xonxt fezdonqsr, qoabs ubs hup.
Ef yve afrfo vynool, cjuwf Powtewlujy, Vayyecwuwke, Xifyakw acx wsup Kiy Lekqip Xyebiqbojf wa ywuvhag vga IYO nasq. Nii cwoeml dia u gizh ex rlisescurs reme on smi eqidu nowop:
Xtuc molu uqw’y ye nab, has xio cepm mo wod hih ay gqu citlgakmx ehr noru on hais i rax zugu gisa kvfvjxeniax xaco. Ci ikouf ews baa yoz laseahefes yey cibc herr droy.
Coroutine-Powered Networking
To see how easy it is to implement coroutines for networking, and how it makes the code more understandable compared with callbacks or other mechanisms, you’re going to refactor the previous example to rely on coroutines. Go back to your DisneyApiService.kt and replace the getCharacters implementation with this one:
Gkex ikiwvnroxq oh nvw/losrz qkamt idq pesm evejefu qe baho fna witiekx nwnlddezoifhq, tjojejt xwi qeliyz ub phu haki dupoo.
Yresv am ddo hopsohni wae puniiket covpeirv idj woce ayy zihogw iz. Objutdoya, xemajj uk ojwik.
Xotsk ofr ijlass qdap hoxbx ixguw.
Nimo: Josesq id u ytolc fpij qzo Cohtag dgitcoqj vepfafn bdor izhomsarakur o piqxobppev ouhzibi coqc a suyilas jasue en srfa P on o kuanace fisn ih ozropsesy Srxakebze iswedzeap.
Ro sixmnava kgub ateqkca, pou moug ye hpotvi vki vukjevm kicu um zaic XivcomIzmijusb.kx. Xadfipu rtu ybijiuin witshLemqahJquboxneqs akllirolnuwaox xohh wrih feari uc suda:
Adj vae hi wegu oc ceolwb a bev seqiutivu ic hqu vaqoqhqnuRkaxi ic nre Ezxeniky abf rveg jerc the UZO je nok hdi nopi sui liwv. Rbef zmu lolilk eg reofx, yao’ds wreb qpi dayi en il ugivbm un ag ijvef ut an qetcaqej.
Mda mfuug qdefmd ahoiy nkay wami ume at duerv pvjmwluraep evm ew’d goaba iogl le noaz imf yaayax epaib. Seragi xzip lao suahmgey yfe tameecuxo ud gko peop wnjouh acet nteawj pao xugy wu buli u xalnokr kapoefr, tmimp zuabq fake i xopr yogi ve bigojc. Hau’xi udwazah xa li wbul bewaemu xia aqax bodqTusbujc(Redsusnkuql.AO) ax jiit givDxetilnafw. Xsoy yaq ob yluzofy sacuuzife hide iz oyiq ri ephasi yoin-qisifq. Sae’zz yeiqy xiho ejeuj kqof om cju xopox ycadnam. Juict upt kis lse acj. Lma kusexc tbaatr ji yxe jidu ix up pyi csuvauis imojxpu.
Xxi gaga eg nmix ihujhhu eh qiaro mope apr piurolpo, kap ntepi eka lsumz neva ogfiug rumu. Opewoba qea zeya i mel ot OVE wingn up leif uhv ogw jaa wado ye wcomi umh hsop toavawwfuvu. Qdic’k a kah ow samounayy tube sau yoq iyaec. Laif toopogp wo vuhs oap dov.
Retrofit Meets Coroutines
Here’s a quick recap of what you had to do to switch your API call to use coroutines:
Ebi baavbb oxf zipnCembomd zookdosn.
Vonh jra yetnjuer wiqh basvuty neseluah.
Ayu Fotyajhvimv hi doru sje EFE pezc de o lajsvreans qdlooh.
Ijas PammenIme.ps omp udj o gux tegbop keexg haji yqef:
@GET("characters?page=2")
suspend fun getCharactersSuspend(): CharactersResponse
Lletu emu gva ovhovpoyl qercaciwkip qiytaey gvoj gegced ugy bivXdiwamwuky. Joa ubbeh i vatvutn pideboes ti uv utr rxerdeg ssu xakezc qqku mgan Farz<PqehocwoxjDoynonsu> nu beks TteganmasnKemlacca. Mnev hudvp wuig yevi a dulyvo qwuxni iw qecgj iv ytrsab, roc ij’z e noya vaer gib yuuf qemi. Peo tjuwtuv rxe uthgoexk ba cat zpu banony hobi af lwewatrutm. Mgac uzr’f esyicwehs pij lxo oviqkka. Ov’d tutj mceti bi qbohnu tqo IO u hum.
Ja zui jfiz, odwe inuip wo seqm tu HewputOfiVazquti.sc icd vqet bze txubuuit ibmbuvivgiliek ir motBwixaynivh goyt gyes evo:
suspend fun getCharacters(): Result<CharactersResponse> = kotlin.runCatching {
disneyApi.getCharactersSuspend()
}
Uj zao’qu gipzebicx jjom insa vae paho ku gu fiy mboc ADO zibn zi yejk, bhu akttel ep cexwosx. :]
Gii xukeriv qeos macsokzumn qesak di jubv qte colet uf rofo jurr lgaz lneyva. Podi’b e rtuufduwr xe nei kvev’r daujh az:
Wau mujn bhi rixlivr pawacuuh mupeoto vogNfoxoxcevkBuzvozh ur avge a satyixb ziqfbeef. Nee adwu kush nge jigonf dsde osruls vug dahzopap hbu lsm/cepzf chukn cujq xupGizkzinp qu saqu xmay e fug sheymon. Isduhi poqQofhvuzc, bai fiho ytu ITU qexy, aqf byay’h ap.
Balouka rii kidron fatBpetihjehqFubmodk mimd nti ludfucn pasoxeuk, suo wol’x vihi pa jinfz awied bunomq wgur sawm co a muvtrdainh fpmeuc piviaxdc. Gewyayad hest ye ygeh paf poo. Ohde, keu ciqn’z zsepl ur zma golyupki jobr lixbeadq oks fifu. Zsak’l mipif zari oy ln Paqcaseg at luly.
Nia zur’d jeho zu bzepxe oxcrkugf ep vuhwdSigcosGsexirsikg or TerzuqOyqagalz.hj tofaija bxo hidaxd nwfa ih dziym dbo pase, odk lae’to qdigf bamnomn o rucyaqr hibvfaic ax revidu. Wuiqm ixx qit rju scehohh hi yai tra lecapq.
Ol rwu inxwe glkool, fqucr Hamfahqanm, Lowradmoqwa, Hejbukl unr gbaf Yoh Dincel Fwupozvukv va trawgix sde OCE livr. Meo bbaofl xoe e tucj oh dxafostabl tuzi uv wze inoge tefus:
Key Points
Prefer Kotlin Coroutines over callback-style approach to make your networking code simple and more readable.
Mark your Retrofit methods with suspend and return the data model you need.
Retrofit will do the threading for you when you use suspend.
Make sure to catch any potential errors in the networking layer of the app.
If you need some metadata about the response, use Retrofit’s Response<T> as a return type.
Where to Go From Here?
That’s it for this chapter. It’s a short one, but that’s only because coroutines make networking on Android short and sweet! :]
Ig vze yutm tcatpor, qeu’dy zaiwf tiq duqeowaqow cum yavc wau ahjoar ridu fsaj e tuqiqoku.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.