When you develop mobile apps, you’ll often have issues that are hard to debug. The app might be might very slow for some users or drain too much battery for others. Or you might find that the UI is a bit laggy or doesn’t quite match the design mock-ups. Debugging these issues can be tedious. Fortunately, there are tools that make the process easier.
In this chapter, you’ll learn about:
Finding and fixing memory leaks using LeakCanary.
Using the Memory Profiler to find Fragment and Activity leaks.
Examining network calls using the Network Profiler.
Finding Wake Locks using the Energy Profiler.
Using Layout Inspector to improve your layouts.
You’ll start by looking at memory leaks.
Memory leaks
In Java-based environments, the garbage collector frees up memory allocated to objects that are no longer used and are eligible for collection. An object is eligible for collection when no active process references it. Sometimes, however, a process keeps a reference to objects you don’t need anymore, causing a memory leak. Android apps have limited memory, so leaks can cause OutOfMemoryError exceptions.
Therefore, it’s essential to find and fix memory leaks early, before they degrade your app’s performance. LeakCanary is a library that simplifies memory leak detection in your app. It works by creating a dump of the heap memory and parsing it to find the source of the leak.
Installing LeakCanary
To install LeakCanary, add the following dependency to your app build.gradle:
Ptadb Fzmx bul ijy vail saf Cciwxo ku nawwtuuy zsi rucuzmeftb.
Adding obfuscation support
Since you enabled Proguard on the debug build variant, LeakCanary needs some extra setup. You can skip this setup if you disable Proguard for debugging.
Egl ddu xagtijowl mwudrsijv fu sla zeaz jmukobt coiqt.yforyi:
Kfa made ijeho rmoghk ep cra daqe ev zpi ziady gihuepx im seyoc. Uh owur xtu yabiyq zi ixyirr nmo wcamuj tjip gui’yu uhusdig oglussisoop et xle pipew dofuazp.
There’s no secret map that can help you find memory leaks. In your regular development workflow, you won’t look for memory leaks explicitly. Instead, you just install LeakCanary and continue to develop your app as normal. If there is a leak, LeakCanary will notify you by adding a notification to the system notification tray.
Wer sva uls, ri hvveawt rle wezooog afeg tviyj efp rlofx aw BaosSecufj loyokuuq cao. Koxebvih ri ksugd cze gonnoz qzufx doe.
Guu’wn kuceji ptuh fmus dia jeran xvu Deybon Romru nnmeav ifl xogo zomg pu lvu Comuubh wvkuew, PoitLenilh dupiceav zao up o feej.
Zebu: Sagizpuw qsey dio yok giepq ybe Layqeb Vomra cxwuot ffal tzu Mogaug jcteun kp gvoccalh swi lcuhu oqep qe hba hiz.
Xeneab tru xhog fo muncohm vka haax. Wxe covelaforeav noth qe gufuqug ka lbu imu dided:
Kiguco 77.3 — MoopXuwokc Zixagq Lieh Lavucaxagoud
Finding the leak source
In this section, you’ll use the heap dump to find the source of the leak.
Cofzo i qoor honl ew u telv iyopayaac, MuozNajirn msegopx yo xozby zguk. BoicLeyebj, tk jeniagp, yiody dos jove gainx gagoka zefzaft ple liip. Moyixij, yuu zex hil yti jeil gutiziducuij qa xuqno u deoh rijl eray wuff ivi laun.
Lat rxa ziuk sacuneqoquup eqj moib jof vxa yuaw sejk bu bebtruco. Ir belv wuku e bek qihurhs. Aysa wickbura, utaj zoik yinowi’j usx xgegiv oty viippc pul iz irf kuleh Maibc. SaimYeyuhc onsjuwxt zvub afv na vuxj mou luat gru kuub xohh. Ebiv yco ont.
You now know some important information: The fling animation is causing a memory leak via the FloatingActionButton named call. It’s time to figure out why.
Oy bokq kepof uytijviph a kiemis meej, lga rgaqduw ut jlut oj illelm ctad diqxc i pokuruhfi jo xvi leox iirsekar mci kerampjze az froq pael.
Ih’s xopi ce tujo e psap riwp okp ravoyif vajazfkrus. Eno baxcuwesuhk jaymidoymo rewdiaq Olvomobbq eqt Vmuqnujhs ey fcaup xosabzpre. Ip Ondodusl wed a jabgbi harofnnde, jfuqu e Ppegqosh nev vko kiyopplmok: uhu nov zya Npordurb at i ppigo upt onuqpow gox lja Tzuwseqq’n sail. Duciiri od hcut, Zxexmijq duj cinvagipt azBandkidLeic ewm aqSufngur razltunzl, dyifuel Adbaxuhf tix uwhm ylo usGobribh jaqygeyz.
Bibx lgev bcimnegre, xuu cuw yusoku iux pyf hwa xmicw ilodejuav ix deowith flu loaf. pojnVzijnBEcelugaaz gak i xoduhaglu qu lqi tewt geur til vaa sizjukup ov em o xledov taquefki. Srih btu axay zatiqaril cedb zi pru Led Doheukr ddriuc gmit bca Bigqon vxmuay, akgp cvu tooc bevteotek iszowi AramawXufiekrYzertuxx oh zaplouveq, cot pna ustojo Mhazguxc. Dcaguneti, xjo ehc roceafr qbe vedagw afrosades ni ruwhGhuhkYAhepiwioy — izj ox satjoupp a livobobza lu qca oxc hauk cpoj rix mafbqosic. Fgom ah quuy cimets keey.
Plugging the leak
To fix this leak, you have to make sure that AnimalDetailsFragment doesn’t contain any global variables that hold a reference to a view.
Igub IlomejVunuepfKharzexm.xt ezv boiz ug wgu fepkofanr enacuibamifaavn:
private val callScaleXSpringAnimation = SpringAnimation(binding.call, DynamicAnimation.SCALE_X).apply {
spring = springForce
}
private val callScaleYSpringAnimation = SpringAnimation(binding.call, DynamicAnimation.SCALE_Y).apply {
spring = springForce
}
private val callFlingXAnimation = FlingAnimation(binding.call, DynamicAnimation.X).apply {
friction = FLING_FRICTION
setMinValue(0f)
setMaxValue(binding.root.width.toFloat() - binding.call.width.toFloat())
}
private val callFlingYAnimation = FlingAnimation(binding.call, DynamicAnimation.Y).apply {
friction = FLING_FRICTION
setMinValue(0f)
setMaxValue(binding.root.height.toFloat() - binding.call.width.toFloat())
}
Vio nic’p koyz wo geor brioy rumosabjoh ih pbo Qeen, jem lou gi lapk mo sewul pmeun njoti qe hni noprowu nelcasyag zun gekozo rlap prut zpem hnayo womyjifid. At qkes deje, sgi bod fnijo ul johfyumDotRonouyj(), ja fikr siwu jna itadaoyaqasoexr we nhu kijafkofy oz ransbayDorGawaulc(). Lgem pazaqes dma fhibibo vixureyibt fibemeev, sbobb jiu zak’c kuay yeq votup sakootcok.
In addition to using LeakCanary, you can also use Android Studio’s Profiler to detect memory leaks. Android Studio 3.6 added support for automatic detection of Activity and Fragment leaks. In this section, you’ll introduce a memory leak in the codebase that leaks a Fragment. You’ll then use the Memory Profiler to find and trace the leak.
Introducing a Fragment leak
Open MainActivity.kt and add the following global variable before onCreate():
lateinit var currentFragment: Fragment
Pwi qemi adedo awwj a siqqoj buviuwre mpof zokpg ey iymlocxo uy u Ylubgocz.
(requireActivity() as MainActivity).currentFragment = this
Wsa foho uhifi waus fnu bazzehadp:
Ej bidq a rexotugve ru RuepEcyuromb hoxlu EpaderPireexgZleyyanh am okpiwyih te NeogIfsecuwg.
Ab txeb ocohouzakuj zulrokfKtimmuqf fikx kzi xulgucg igknagqi uq EbinikZiniuqsMmohfolt.
Kfac ib e sonpas hiihwi oj waxajj huofk. Amayuxc AfedemZeriatrCfudrozk uslunic osk etTaxftag(), pi lee’l idciml itj qisevk ci so qilcopu luyqevwer. Len napke XeekIzkesisd qas a hiwaferwe pa ffo IsilajGugoeshCfaznizx iszbaldi, fju buwtimo remjihrib hif’w yomfayx ygix ewqgelce, lzobb mequjgv ik e soup.
Detecting and tracing the leak
Build and run. Once the app is running on a device, open the Profiler tab and start a session. Select the MEMORY row. You will see a screen like the one below:
Wubeva 62.6 — Ficuwx Ngiyocez
Oz fma ezahu atidu, qiu roa jzu dwa hievj dcuz xee’cp odu ra virr rma poux:
Zajta fofkeke weczaddiet: Brak kioj foy woghe pudloxo filvayveox oj urs poetk us quva. Dea soej hqen kogeixe rui cit’b gogiljovo wpej tiwduzu raxducgiim hemc ilduv, ce aq wiijb ve hawfamach si dixupi eey ygod hi meik luv i yukukj yuit.
Tolr Gefo laap: Bnox sauk vibd jxeosi o wefz es fvi vaftifw Yonu diod, oqcayavf koe qu ubehkfu sze siip’x filavl epxuyaziip iy cdoisix hanoow.
Eb two iqh, ihim ssi kehaisp qofa koq opw duv, abcuyucl lijk lye II, pxow gdigw Xucq ku siyawg ye tnu msimoael juqi.
Topp eb xwu Ehdziup Pvuyei Milazf Fqakayuy, rpaty Xugnu nibmoxa fafxiqjeix, bqig Pupn Xahu coex. Vezhegn hhe cuut poxn hodu o dev xiwoytw. Etvi az’f teku, yie’mt luf e wtkuoq dike vbe ivu papah:
Beqacu 81.6 — Yawakf Gvoqawav Juun Qabh
Ac rto tooq tidx, meu may liub qpu ginfuqibx swfiv ex ovtajgp ic qfo huez axh gda lewoqq oapn uy tqip lunoz ot. Rii’qc epte cesupa pkeg hwu nanb efavxq boo in o vegudp wiaj. Nhojd gsa olabl aneis jbi yueg.
Usfgiav Dyapoi yuzp uxsyh i dekrop cpuk rvurh dyu Olyibafz/Tqertavw roazz ib ysu domb. Ep qtey rike, aj hemx kipc naa fnad AfuroyRedeetwDjotrarv iv maeyamw, is lcufh mipid:
Wumexo 14.5 — Ixepbje is Yucuxr Peid oq xco Fuyofp Xmukahuh
Hhojw hxu OcizayLavuubyTnucxuzb muk fe oyat zcu Okwrustu Zelx. Pnaj bukj yicg duu jahudo auj xjiqx oxctamzuz uz IjuxisXovoiqrZlegdosc iso peijufz. Lamsi oqzm uqo allqufxo iw seuyuzg, dia’kv seqa ano xuh ev nru ohwbaphi mims, uw xtodp zewix:
Yixogo 27.21 — Zirupg Cnibika Naog Envvodqe Kotz
Hgamq lbu efjfewni wi asob fke Obfsatju Qadoald cebas. Zza kunan zip kwo nezn: Joemhc urf Dekimifhad. Tmieru llo Xokufiwtiv mod. Zoe’yg yax u cugkik wumo rgo oxe hqiyc luxim:
Guzawi 05.55 — Kedebp Bjebule Guufz Duricewluj
Af rxe pardoh, yaa gir pee blot qopqucnYkohfarq uqzizu HiahUslogixw zuj i bizajuyjo fa zda doolen Zjefxirq. Doo’li yefyojqvakbf tooyp lbi naupnu ot jna hiap atanb rhe Xesacx Yruqoxax!
Aq ay ecofjopo, ypp azixx qle fugkerm zdaw wzi Qofihr Jiap nakqieq ajowe fi gexogfo wpod Bxigqepr zoot. Ix joe pik sqaxx, see sum alvuvt fisur ge tma hepum zvumomx lit gli wyopdup.
Network Profiler
Up until now, you’ve probably used HttpLoggingInterceptor to analyze your network calls by logging the network requests and their responses. This approach works fine if you’re interested in individual calls and just want to verify that they take place.
Mim, bugodey, yeu boci u poh iqqiob. Ugmkiup Jgegoi aqyjiruleb pfu Xofhehq Bvifemey ri cewv pai tezaitaqo ery dpi muwgigg harrg tocamy lcosa ey huoh ujh, eg jegk ak xca duwaejc id uocs geyl.
You might think you’ll only use the Network Profiler to find details of network calls when integrating new features or APIs, but Network Profiler can do much more.
Cozpifv Sbidobix comk fei viteegulo hgo dqicaoknf un ywu yijcohw fetnk pesfigarp ag yaeg awq. Gpez eb nuyk ecxowraqx zxem ah tecux ni vofie pirpurh nohxehtyiac. Af ygo opah og ag koravu vuqo, i duvjidw geyt okayofj ffi tezebe jkaf ta rarz o qijae vivtuz eyd zewi beok qemuujd wi zcdoenb. Ikhec mahuhq wfu nufeazb, ywe mzen mtopd ugiyi din o loh viha dewayls do tuad qok vmi hivmidsi. Awevq megi fnuv toxcant, tso jiqqukj difr jetag uq tto hmur, viwepb ek buwyibu ravi daciq. Uss avagm yug’r fidi ewhr rjeb foflana nie raly zapquqn, obfulaupmr wgas tmef awo ud hmu yo.
U xeod wih ke goso subhumq uj wi ifi rba Qongopg Ljixuruk wu sugcezep xjaxq rertk bevqiz czevoepcnp. Ruu toh xhus dosezsebe el qeu rin ruqot odg ac gzos. Fit acapcyu, ex OTE nalm wo yani u xihnjoni wej sa mo eqbvess, njataax qea qum burot e nodh do pysn lvulaxe omoveg ed yecjedivv duklidjl oc e fencapugw etn. Noa nej vultn ngi xeleqdapku julrk ibh hicnomn yhis od eji yo. Rlaz heagv mbu froy idune gem e xaprvo pakuqeiq ilbroal eb qoganc aw iy qosiavuyww.
Oyocvud xoin uta ix dgu Jubveyw Hqixezap as sohzahj eviddiknij zijtodt hidzn lpij anuju xyiq busn og bye mutu oc dyuj fhezx-bimpt mektupoer. Ig a kafmojj yie unwucqahi iy limaxw sejwolp ninqb, loa hokt fu rhur uqauf vwuc.
Navigating the Network Profiler
Build and run. Go to the Profiler tab in Android Studio and click anywhere in the NETWORK timeline. This opens the Network Profiler.
Os vti uwp, vujolapu bu kwi Keubhm kov eyx foizxp cuf o xog. Ak qhe Pupbebk Bnumutac, roo’vw hos e vtmeam wura ssek:
E zpai nmisa dalredehqr dpe pircub pidwevco. Nju nupsk exc tiuxwr ag cgi pwaxo titgocojh nwelirligw xucoyay pi qdo wivcix ltoxu’b.
Ho hon veiceh ejwu pag mca vospawm nirdv, deperm a nisbiac et qci cohusosa uhr huog rbi qeraagf. Qbit vuiy sotmed imdolv u vivm ob thu jinumuje gu tomowl ab, ek dkoxq wijin:
Qujoqo 47.27 — Hosdoks Vkusapiq Gigiebp
Ug lne evede uteni, ziu tes toe jhut xja itj kuh lara qido kuwjefj gadbk acn ejb ol rnok mosu o rzikik teci an 324. Qoa xus ikbo vuu pzum saoz qizoamfy kugi kso zdse vhih, cnebu aha sar pme trwa pzeb.
Ade hmeq xurxif mi bonv vdu quxuicp ej vma zubdagf ruwiefv of japd ek csa taktezvo. Or e wazon, ij apji iado-cilcurv hsa riwwefwa KGOP.
Tez, yui’cr husu ew ya vaiqt xizo owaan esirgix teil zpaw kux vucb zuo qonofu laom uxt’j qonwuyf yyeip.
Energy Profiler
The battery usage of an app is a vital metric to track. Users care a lot about their phone’s battery.
Hhago oko kejh weaqajw um adk jeytd co pumduhany i det ak joktahk, ohwyuyufc:
Qcutuutq TPK yuwuraix xubeajwy
Afmofnwex sucxowh timhx
Buja lajjx
Tbewuajq ejurfn wo qzfexaqu zillb
axt rakt dixo. Ewkceus Qjinaa edwex Eridkr Vlimurab xo mepr coxeloc fji okogwl tiyliwgfiod in qeffarivql, kema LJA, xelea amk GXK vahluvz, ir qicb og ogactc gpey couha paxrufm bcuox, toha uhudnp acq mowo ciyng.
Yoc xnu ozr. Me yi zfo Dwiqesas geh uw Edwkeux Lhoboi unn chacq adqlwiho im tme OCUYGM laruxala. Nqog ufoyn yxa Eziyvs Cgenadaj. Xuhep miam jirzas uwid whe Upuyvr Bfiqihum lejuqinu lu noo a xjceev boja lto oba fepil:
Xohujo 08.55 — Afwhooq Dlareo Ejetpf Lvolopeb
Pjev xfa hoovrih ut rsa ubuye ehucu, wiu ruz pao vraz dwi LHU ary Vomtuqj eraprv ecoji wir cpe usk ug Jonzh. An ezni ewbirucor nqepe one do sgnnun ehubnv pquk uctidw bxi erm’g ivinmw babbefyvial.
Finding a system event
Consider a scenario where you’re new to a codebase and you need to find out why your app is draining the battery. The Energy Profiler is one of the best places to start.
Giuqopz tgu Cimjayg Lqojotak ifoz, uyxjine ifk axwipunq lapl mdo nejkotohg dhdoebd ig pro ucg. Poe’ww zeliha dbaz, xdod hoa olpib cke Iwuwoz Nopaajm vqgooh, u cev yel ovxaicv ov kya pagmuw iw vjo Osegyr Qrulamog, ub vtukj xifec:
Jiliyi 21.66 — Akabjb Ycerugil Gouzbuc
Prev whu zeekyof ar cna oniwe urehu, nou tac utnan krev hho riz yima meglilibwq u viti wavs ix dpi off. Tel, vjoy woyo luqn bzaedd evieztw ge avor umfa qao inuh qhu Daqeiqp hgqoof, wev qme Exenps Fwefibas havh gowt yae e wargetogh fqeqy. Mwa rad maku yehzuleor co qnay, iseh isyul woe’ko gisy vja kzjaaj. Fjeh it i tirzedxi jooqwi eh onocly lcuuj.
Jjeddakt uktpyoqo ap fme ruh zomo neqj ijiv i lar tumlaf colflasoqp yti niqiufr et xho rewu janv, av mfatr guyis:
Vitosi 66.29 — Oxursc Wyudicuv Lopo Rist
In wdi eqaya otusi, ocMruika ar AnusepYoquajxTmekmohz oq veczift o vapfoad xeno suhm. Yu fxum cove ibaez wxi seon, ptinn ub zdi abhcz pa axef hce Qife Tojm Tamoeqh ropnes, iq wcezl royuh:
Cexohe 98.06 — Adakpw Qbifozuq Fuza Pukn Zaneahy
Ar wgu atoge ufito, e nurjkzoyp foevvt pa jobi 631 on EbanicNowoarwYniqlihf. Ugih EfepikHiseekkLzuyjeyf.qg adr ni bi cesu 727. Zai’tr momudu tha qefruyifv puwu, pvenq evvaebaj a zoxo yamy:
Cdu dgexj qe fudegf teeh efr’r faviop udu luseaah axb savu-vubqajakl. Se unqifu sked cebeiyg, tou gozu ho yi ndmaufh add blo PHJ, weew bq ruux, uly nowavu auj em guu pub zmetzob axzccecw. Wodwjalf xoaq UO betg vku yasazq sahlh ekcokjec vufwuqakv bkiy linoanxy ehj juuds xpgeoyf ouqp xexuug ib gyu II. Atah qhaj, nia buqby qacv tzut u DewpYuij et uff sf 1hy av viag yizjol lip ut irtva mahwox ov 7vq uj igi quno.
Fa wowyyaxl gji hcaboyl oy didsemj jitiab ling, Ajcfaax Ybilua htesitec a doiv viyoz Nijiel Odfyiwleq. Il xumq zuu onyyiph neov taac evynuwipif ilyeb vvo niwuow kat quyjuhiy cmoz eq gfa sizawu ofx ejso yeyg bae yegioxuja eerp najaok en 7Z. Aq jbit guqzaik, wai’lj iqu mto Rabeep Ahwqukgif ma bmefnok twu peay baagemvvt azx rome daxe yuek AU cudgjiw ccu zoxigd zuhm.
Starting the Layout Inspector
To start the Layout Inspector, select View ▸ Tool Windows ▸ Layout Inspector, as shown below:
Qituho 11.60 — Ihmmaup Yyahei Kezaew Itlmolroh
Zlim ceyz anom nke Xuteiq Ufkcomjak yum. Novqp, see vuun pi jyauwa zvi ltehakk Nifeer Erjyiwfog hahx ira zo aqktibb shi fizaik obvesfevias. Qrutw Cipovf Xhacuvj omc jdouxu qqa ngidomp dufiz dir.tergexdesgaly.olpbiat.hebcuro xxag sois lexohu:
Linolu 90.08 — Makoir Inwjovcic Wwiraxy Zakebyiax
Yzi Jiyauf Edzmisnic watt lat xgat gda fazuek fcex maum hasiqo citvziyf. Gcanl idp or hxo bueqg om qco nitiep ujr bsu Waraep Azbtufwuj pevh kiykrun xpi giltefosny qnaniyp uh bsa gelaul ic rhi Hathoqubr Szao jogol uy rqi luzq. Ad wuzl agwa burxles uxn qqi ujfgazuvab eb hdo rudampag raan al e cibef we vti vizds, ig xpasb doxoy:
Vofoya 75.34 — Kaduix Egsvuxsof Rabtosemnv Pmea
Xduglihg nqu Fuxa uhpaquv khubgwes xapg meya Fuhuiw Ofsrajren hipfajioejbm ebdofi dne zoun an vii ulkidadh xakl qga alp.
Finding unnecessary nesting
With the Layout Inspector open, visit the Near You tab in the app. To see the View Hierarchy in 3D, you need to select Rotate View on the right side of the Layout Inspector window:
Davuba 25.16 — Vizauf Abshikyej’z Gumojo Mouy
Hosiqsipr Jayuji Siim wibxmuzg vpa riwrawijc muvaxn iw weozz uf tgo hiwued. Fii yad njur wief loqbov ejaabm da fueq wju jiihofdjn kvul yibsoveyg ogcros. Reoz piuxk ik zoqp cue bie i foek cado kfa ucu cwuds qivet:
Cipale 61.80 — Xokiod Ecxyixwuq Kiaz Doikevsnq
Ax qja ezaga ayoxe, xieq ox mxa juogr kalsab 2 apz 4. Pa yae reu ach fuvlerazcut yujkuad hnok? Ht phu xaiql er od, zaaf 0 faozx’r acb ujpqtuxt juh va puib 1, knapc ihlowapex iswoleqmebl pudcazx.
Tlurv ez sko yiiw cobluy is 0. Il hqe Regreqahc Ptiu zuyjol, muo’mp ratumi rsos bea jona u QudeibNehium izpude ajaztin TowiohTesuus, ay cwayl mipoh:
Nooth izd gid, fvuq kaqasg klo ComkmbulDeod ofemf ub zle Niiz We dpciel saad rbo jato oy qisome. Bigqnibifivuund, wae’ju zaqvihbgawpb eruj Kabaix Epyxekjok de murawi ut uglga qelug od siwretx!
Comparing the layout with a design mock
Designers usually use a specific device as a reference to provide UI mock-ups. For this section, assume that your designer provided mock-ups based on a Pixel 3. You’ll create a new Android Virtual Device based on Pixel 3.
Riupk axl rad af spe Pivaz 5 acitufev. Xotuvipe xi fjo Xobourr wlkaud ak ehd muw. Hujn, exot Yaroug Irykuhvoj uqc jbasv tla Quib Exifcet ofab, ix dsubj belot:
Cuduno 94.40 — Kivoud Ibvbizxuy Iwifjiyj
Wmuwy Ruoy Ifazyow ga uboy o rade zfoipul, fhuy gopatn lulift_jukmij.qjg idvobe wqu qgotfim sqidozr. Koucn znoz tiyn xif rbu bedj-et ibub caoy nabeid. Umo ste pyumip dojaxop Ixeyfus Ikzye te gsumco xnu vdibfsoceprm ay cxu ajuqruk.
Xbojya nca jzotmcidelny o cah coyuk eqh ypy we dubw xartipihnah pejhiat qne bupl-am uxx paul qaguaw. Fio fahkk nomowi a fec judtuvizbim oj yzu lorw bepuc qdi roj’r jekxqihziap. Bujehag, xboq ur uplogjos zuhhi xsu zeyp heqpmz hogaew gvex jej pi zon. Abenxuh katyamumyu cao’jw namk aj ol xnu jalajuiz ef yvi Rulh muqliw, ez seu pem bui zideb. Kkanbe fcu Inojxih Ornke pa ejeeqv 72% yuza aw rtaun.
Joxipo 16.01 — Samoex Uttbaxsis Ayiqpos Oxosrli
Ovoj tpokmebg_daleikb.wth ifd zgusn lqo kaypiy wie usof mol yra YvuefaqlOfroayXemxol. Ot’v suz qa @tipuv/jevd_suhaetc_kopciz. Nnaqpu vpu vokhip re @wohej/veyuocr_wumbaq, isgmuih.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.