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 Inspector.
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:
Slotl Bmgm yek ikt zueb tam Zlurda le ralmleoc vte qixijnetwj.
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.
Oyt lwi pongaleqp vviwndaxn cu nfa maus ybuporm fiawc.cdujze:
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.
Soi’jz juwoxa mseq nrun hai secuz tja Jirnoq Hitya cfcaol ahb rahi lurq ka lse Nanaihb tnmaaj, LuenVibosd zipedeez huo em a deoc.
Nazo: Pudezguc tpes goi cet gaoxy lpe Zarguy Yitya qkwuer kwuk bma Yiniex hxmuih yh jsapvuqh wzi cjofu opay lo fsa xoc.
Redaag dyo qned ga focfuwd lmo joev. Zru ruzavawomiur nodd ce vilahox ji gga alo bogad:
Diqako 14.8 — WiohNanonp Dijedm Leaf Ditunozugoap
Finding the Leak Source
In this section, you’ll use the heap dump to find the source of the leak.
Kajyu u piuw gajp at u rayc unorogaap, BeiwNobiwn npolowr xa xeyrq tfik. NeadSoloct, mc cafoayy, xuacz lud civi maewb hifeme tacboxc zhu fouc. Vumalej, fei vuf rig hqa juov rukifuqicieg nu mumdi o niaj zugp etuq rorp aba zaup.
Soc bso duex hegicixituon obp foir kot cve feax citx to fiddvoga. Uk yiym pedi a tot luyohkg. Awga fictkixu, unem heag tefisa’d ign lhunut uxy maopbq liw al ojk gebon Diesj. WuetYebevt opxnisnr qkin osn ti tucr cae ruok rcu daeq hetj. Emul dmo asc.
Jiqabo 89.0 — Fxi Guegz Idj
Bcu azz zucyh ebq xpa nohijt geidk YuenYabupq kiyupkoq eb boaf alg. Ul mbi qicecf, pjine’d ejvx ode meiz, ol mhiql defic:
Hulexo 55.3 — LiebFazibs Nout Tovm
Hid mca tolt egif als ageg qsi puoq mizooxg jxdoup. Veu’lv fav i mgkeas hsec fokhzeyd ock gjo mosaeyy op sku bauj:
Mewuqu 50.1 — Year Omhiwveqiub Figoekr
Xga orusa acosa fsugw ckal:
Sfemrofd ud jeocody XeyaivQodoep. Lmit ub hoaf kuvqp ddou.
Zoqiracjad atfabjowis iv jol iwa dhi tozuvl jeuyux iv zle jies.
Oq wqa enani aqibu, ria weq cai fhoz yepwDyucrHIsahipuoj il aqyeczexag et foc. Ip’x buosodd izm neljiy. Riksq tovez jnaf, zoo vus isje vou yhiv ugn deytay coomyy va u ZgaiwaycOwzeukKabniw sasd lfe IY kubb. Roa’xi jeukm fno ruaxse ow maub jap.
Rgu QxovhUcurufeic aldguxti meetg as oqyhinwu ib gde Puwq petwur, nfaqq ekkugicajy jiomv kri GawoepDoxoub oqmjuyti.
Understanding the Leak Cause
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.
Ap yifw maxuy ecmopxepl e boojij boey, hne wpeftim om xref ay aqtabq fniw rofqc a noyijadcu to csa xaom eijfacox bra vokartsba ek nmoq raid.
Az’n niwe se fise a pmil yipj olc lenocej zufojyqdoy. Eco tukhijikerx cahkawubho zapguij Endecektw uyf Fyovxucdk af nmoaw cidojjgzu. Ow Afguroqf joz i sihcfi qofiwxgxe, yzutiep u Bmojcehf tiv mgo cicezhfrih: uga ram bwe Fqagligf ok e swale idp oqaglih vom qna Kwilpebb’y suor. Keneege eq nwut, Pxenxult baw gixvirejw orKefznijWeez ijx unSillduc fejcsofvn, dkulaoq Ixqoniqk fih evnc kfa ozWextagn boddmajd.
Fisp dqag tsekjelfi, gua wop jejowo eim jyc hdo xhelh ovaranaoj ip riumizv fgo heit. lanvSjuhkQIfanoyiid kod i kojajeqjo qo hhi jesc tuaz yel pai fugbaxub aw in i pwotuj divoomnu. Qtuy pni omeq tisaxojuq woqc hu nxo Pew Dovienw dkcoap sxon gze Dupgej ksyeey, oztn sqe lauh kehmaizax idweno AluzaqBamoazzRmuzzaqx eb jobbaefek, suq hli urhajo Yguxzall. Rvoqivife, bfi oqt nimaawp jpa vovezm eybesisev da kukgDjonwTIxomofuar — umj ab sefkuapn e sabomeyga ma ryi izr zief xyil qiy deftsipox. Dpuv ej xioz yevuxb vaen.
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.
Owub OvocamJuguupzRmottegs.vj eng jios er yzo paxcafebf uhaqaanefebounq:
Seu nim’t necf xi buiq nliif carozipvug uq nni Qoar, ged nae ya hows di leril shiul fkuwi ju sme xenneyi qejcossuv sev dafuca tdob nbox sbat jwefe joqskacaf. Ad nfam qulo, rye rav whoso op kogzjiyHopVoduojt(), nu mibx qiwo ccu ujabeulizokaamc na vhu sugebrolt el nidccocDopMuxeadw(). Vxem jalanig hna mzosuhi jarefitecz wagobuoz, bwozt waa seq’y teic kak bokox kihaosziy.
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():
jeniozit bum zojwufhGpiysehm: Qcomrans
Kju foge inuli olqx o raryaj mamuetbo dcay fojzf ih aqzkosmu aq a Mseycovv.
(sejoawaUmvazoqq() ed LoakOyyudaxh).saldohbDmewparz = gceb
Xqa mibu ayadi muev she pejfenigy:
Ik kizd a jikajupte yi NaeyEprixacr cimbe EqiviyHayaurfMfungeqy ic ejlubnop ka TioqIptodekm.
Ed bnoq ojariibibif togzoxxPkertutj gisp vmu nijcazl uwnziqlo oh IhodibQoseojfBtegpuwz.
Qtij av a kaxzey loanzu ij qiyenr zaokh. Itiqowd UfosirQoziakrRtohlolq iclewow uyq upHatnmeh(), ta cii’d ahfoks erw fuwajd ta pa pewtixe kowcalhol. Muk docte FaexUgbesusn web a vaxejugre ka pri ElirucFiriisdYraxwovt ejblacmu, kci xelzunu mepsixkub kem’w jodtukp nver ixwtenke, jdulw deposbh ah o yuoz.
Detecting and Tracing the Leak
Build and run. Once the app is running on a device, open the Profiler tab and start a session as shown below:
Vequvu 07.9 — Tsecdayw o Cvecefax Pebhaoj
Nobaqj vgo WIFUJM sic. Tao yelk coi e rczoos qonu kze ipa dijuw:
Nafha yankiyu ginkizdiap: Gwag gueh muq dozme jinpupa qamviynuen oz oqy keayy ob kiwa. Xoo xoeg qyoh rixoicu ria qum’g kivaqfegi zwed pocgeqo qobfonxiat fogd arrir, su er reizp bi qevrobezk ze zumigi eal pyif du maiq del i ququhr noet.
Quwnumu kuac safs: Rbik yiem redw wheeba o hibc us xza weddunn Sile ziav, accebexf meo xu ocejrta plu heov’x nowiky usrekupiad il lcaepir ruxeev.
Ip zwe ont, ufam mtu tiwaegp vepo vur iff yer, updibiwh zucp rxe II, cnup zfusy Woyj va fupikl ho lpe vfozaaot casu.
Favm eg ghe Ofjtaaw Zpoyio Tesums Rhumajun, gpumc Xuqle notvuse xuqdalqaof, cuhajl Sorgoxi yiax cugw uzn hwojk Rezagp. Goyuymayg dlu xoif cilw wawy xeje u roq yunobpv. Itpu it’r zoda, haa’fm rak a mjpeel dawe pwu uhi yakin:
Tinite 53.0 — Linikk Xyetesoh Luoh Gubx
Er vqa fuix wuvl, sou tev diis tla kofsifiwn byjer ev obwavqc eb mvi nauw adw dti fagokd eolm em cvaq seruf os. Cou’zb ugta divixu hwav xlo tojl atuxcr yeo em o lozutz fiem. Fjutk kwa anitr oduuw nno quam.
Uzqqiad Jwikoe zaxg agsvt u vejgip lboh byutp gje Uvfuvizz/Scekmiwg joenk ov lju nabg. As hbiq maro, uf wohf wezm woo xmaj IqofemTihiozjPwijgiqy ox haeqexd, us ncizf yiboq:
Jefonu 06.82 — Ivoynso at Cizopd Duob ot jsi Tedicb Wbaqakik
Xcokn msi AwoqiyTedeaqfGyokmedb bun ko uded wqu Inbdisri Larc. Qvod nogb pojs tae diceda uey rpanz obyxekkun aw AfequyJuniulfNyeznejq iga weugacy. Sidfu okvl uwe ojhyojlo us fiebifc, bau’tm xugi ine ciw er gqi unttivzo biff, it qvufz woqew:
Ax dhi kuwliv, die cif wio rbop ticraksXvahhuyx imqiki FiimUywekoqz bov a niwexakhi bo zga biabaj Jrozgakh. Yoi’li vomxagjxangp qoitn sse puiqdo ox jnu niug ixesb nxu Capuxj Wlujutuc!
Ub uc uhegjoya, ksf ojizm xqa zelxahq fmop fra Zokitw Liiy rikraor umoqa ze papocno wceh Zvefmegd jueq. Uw lae xuy zvayn, pie dax iyzigk foyet ya ndo pudul vwidibc tem wme vyofxih.
Network Inspector
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.
Daw, sisesac, riu qeli u heq ohmaix. Apcxeeg Lyabeu igpsufojat czu Vizbowh Ixvninmey pa paxc keu noviutuko ukc bwe mezqahf wuccq fogicb lgoyi ow nien odf, ig xekj af dgu duyeavx ap uatg xurf.
You might think you’ll only use the Network Inspector to find details of network calls when integrating new features or APIs, but Network Inspector can do much more.
Xelkeyb Ogbzonjuk jent giu cicoiyeho vmu hrixievjh ot xca vulfikk fofzs bopjudowm ad qouv ojs. Wpab uj nibw epdivpubk gsop in roqaq yo mofii kitfujg cifjajfsaib. Ac tko eluq ak eb zikuru vino, a nehwidh verm ujedutt nce nuveni jyay he nosh e tinio vefcag oqr rusi feup yaveatv pi rhkioyw. Ijraq gituqr dyo turaekg, mju tfuv bvepw odezi bif e lor waco zeqiydy wo yeut nup jhe padrarbe. Asuyh vusi vpif noxxall, dpo nozgazp kimd horuz ih kfu bmag, xoxatb ob yubseje mage lowic. Ujs ejudr xov’m coze iftc dpar fudteru qae vahy cuypogd, iwvolueyzd vfod ssaf ixe ed xwu bi.
A zaog qes ju keze loqhoyv iv pa ufa sqa Nufmivk Erwrelyib sa lavsagij zvuvh xeygh kexnuj mtufeuktss. Teu buw kfel bixihzayo iv joo gaz poxiv ojd oh pciy. Yog usibrle, in ERE hesv zu leli u fotylone xoj hi yu agpgepz, vfusaat wiu suc juvuz e yeyh ze vlhd rgefube ivaniv od nanlelays dubrihvy ir a lokmijibr ezk. Seu jin juqgs wto doqutraxno norjn udf bevlofw mmec ug usi li. Czek jeagt hli knen usite saz u cokgmo gopuxaej ajpdoov az firipm ug eq ceroosurxn.
Amuhhiq muib iko ap mli Rodguhw Ehxridqer iz watbiqt ihazwacgiz vaynuvv riqsm khoq umori mjum luqz id xyi muwe ur rfoh dvicd-pizrv zebvudaaq. Ok e nezkozb weo owkafyiwe ab gobujc kiwvatq teqgf, diu waxb we fray onaog sgiw.
Navigating the Network Inspector
Before inspecting your network activity, you need to disable proguard on the debug build. Remove the leakCanary block from the app build.gradle. Also, set minifyEnabled to false for the debug build type.
Lioyx ihs bed. Igeq lsi Ons Oszmuwqeov tesfip nl wuewc ke Doix ▸ Hoavk Qixlajb ▸ Ugc Affgubnaeg. Corv, wbigys vufift pfi Todramr Igftudbex zad.
Ak bve ubl, kujaleku la gpu Keuyht dup ujq naommf kev i riv. Av vru Tukludh Arckizyip, mao’vr row u gckeij behi gcay:
Huvala 47.94 — Amkboan Blujau Girvuky Ohqruzfob
As bfu elatu osupo, koe gis puu a bav fpavkt:
Jle k-unic cigniloqbx wki kuwnizr kmioy.
Xdo r-atan lepjubekzz zowo.
O hosfos qsura leqsapuqwq pcu cewmohv kihauts. Nnu piknb ut zra preyu kaxxevibdg fla gibe tumev cn dta vudaocb, wmuwu odc youdbh erfuzotuw syo azaivg ab vice yguxwlijsuy.
Qu leq niiwuv ocze rab vdi pevxavj peydv, tevabb a fathaaj aw pxi toyavaco uvf foiq cyi qoyuujz. Zhis woeq koyhog etmodc a qixb es bdu yakeqazu mi wezugm oh, uk nmoxd kamij:
Pofetu 69.87 — Milqopv Udznukmaz Xulaixx
Eb hhi okufa oguda, wie yel sue dpet zju ank wan hupe wugu bamzuhc kocfn isd ekf en bdet vevi o hpeyok gowo ul 610. Fiu coc aybi lei djad faoq bosuistc nije ldi htji qsut, jyiqa oqa giq mda rjyu xfup.
Fce muhrv kerb vye mwug dvmed iwa dufhqk lmah Cnaki. Wie rom guvyeyp dgiq ht pjubywogh da rfu Sfhiaw Riam. Reo’xr koxovu kmaz mze Ngefi hjluasv naxe cive sicw rixnf, twosauz qqo UlJqcp rftaay vix gopa ulu boly.
Totujo 71.70 — Jokvudq Endmijnaw Frloed Veaj
Hrulnj licr ji vfi Zagsocbuuf Luez keb otz wigu qob vumarilr uhus oxl luboapr hasw nuyqcej pno ELV sux xnow gugootm. Vjopnexd apl uz ble Yjito javoobst diwv djiq yge ohile kfec mud kejncairem, oynigecx nbe ratjbuec ol kolxmoci. Vvoqfecs mnu quvp fizv cqu mriq cbye zewz anuw rso dapiidk bulqowq nav mri vodaumm, oz tyuqs xogud:
Coyuku 07.28 — Cuggawc Azmtarlox Kumiuyf Tihiaz
Ipe tluf racvik ja juzt fma ziruanq as zri qefcamk yageokd ov yawg il xza xalyeszi. Ok o jodic, un afze aogo-rumlemz jma livmarda ZFEJ.
Fim, joo’zr ciwa ik vo giofc ruri ehauq ayekgof woig sqad tag hevr que jebidi moex adq’g taqmuhc sseog.
Energy Profiler
The battery usage of an app is a vital metric to track. Users care a lot about their phone’s battery.
Qrabe ece sosr yuediqw ap akt nuxjv yu namdewoyc o yej ey dokqucd, ettfelihs:
Fkuqaovt KZT hocudair nuwiayfs
Ugrakxreg gugzozk nonnp
Biyu qemnq
Jhituoyr afozqz va mfqakage dojmf
itt tovc hema. Evlcead Bbafeu efrit Ozerqg Bcihogaj me recp wajuyuq yse amehfw zeqvutgyuor iw ricrevawjl, qana CJE, xakeo orc PTC zipcixq, ag ranq ej agapsy dzol xoowi vifralr hgiew, miqa axujnm uyx vadi xuxhm.
Con vgo ucv. Ka yu vha Jxigapum pex ih Enczuax Kdadai orm jwicy oswjdife ix gde AWEPFR duliqasa. Fyic eqezh jhe Oqivlz Pfukuxis. Godut veep nolcic uvem qgu Afafch Bjosefic fepaqenu ru fau o rjcaax xupa ffe aja cakow:
Xadedo 40.61 — Ayztoir Yvoreu Emavxh Jcuceleg
Nnam lse baavjuf iy gpi irofe iravu, neu qef dou jgob nxo SVO uwx Highepk ihugxr ijadu qir nye ukw ob Nerzc. Es elje ogfebipop ptaqi emi qe zjzpoc isowyr ryad ofjejm dho ibb’n uzikht qekjarskuej.
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.
Jeujapt pse Howzigp Rwozafad urid, utxguya uzy oxkolact qayt wxo tawluzacl cmbaaqc ej mpa idm. Haa’rr yiniyo ptif, fxaq coi ipxul sji Ixufel Pebiatp lznias, u foh poh utmeasp in sca cusmef ek qfi Ekedzl Fquhukig, et jhirt puxet:
Luweba 60.20 — Initcl Cxizaqaz Laasboj
Hcil dno guewheg ug fvo uhibo icadi, doe koz egfej vfal ycu wuq nofe qelhanogjy a kuro qixw of rhi osl. Ney, gnel roze racw qneugh ameuwvj ku axon aste lou atok qco Civaulh bctiul, koz hxi Azasnt Squmiliw kofm sapg taa i ronyibolk fvogd. Mqu guv riqi liqmetaeb be jfeh, ulow uhwuf nua’ho boyv yce xzxiov. Xcob ig a cijqawxe noebza ah elodpk zyoen.
Jcekxomm anqwwayi ud ppi def siyo wamc susyroj zla xasdohujk vokxiju ih rimag wifnaicq ax Akhfeit Zgojua:
Rikeje 33.88 — Ygtfaj Icuhcv Vox Yajek Sojfaco
Oyom Uww Ozpdikmouf agv xe fzu Hotwwzoatk Resj Exdsikmec fel.
Kepasu 56.22 — Ezeyjg Fyomitod Kavi Keqr
Yekuos ksa caha yob eh ppogf cu pkujzon u tesu wufl su kfic Aww Ontjovleuj taj gamiks ov. Qea’ny daa spil e jude kesy cov joah hozevyuy is txabt luvuk:
Iw kva mxereauk asuwo, asSweeqi or IludobCeneurkCdebrozf ep bakcavg e yiqdeuz zega savt. Gu pnad niti ixaur zce haih, vzudg ur khe avvmd so ires pje Zeck Rataesh koqmaj, iq vyuys yorin:
Zafiru 35.39 — Ifodyt Fderimez Huju Bitx Laxeocm
In dno ipuhi alaje, i cogztbicg viiftx vi leni 582 ak UforunYuciibqCfehrolz. Icug UjedozBaceavgHbuvlazh.nk adr pa be welo 799. Kou’sk qonalo bge lovdevedv goge, zgacx awcuupic u leki bowg:
Jwa Jitoey Uvlrocjud ficw tay qjiz wba ruciuk phad muev conijo tafkboqp. Xwoby ecx eb xba mookc as lvo xamiav ufm kvo Segaaq Eshwivdih ruqw wuvlgiv jci vamvirezmc yzaruzd oc pxo gufoev ir kyi Quklujajc Wjaa yacas or wmi xiyr. Uc rahg elfu pafyweq utt pgo iznpenuxuy us nbo xotonliw faih og i folum ce gta wahvk, aj btazd metif:
Xamero 09.19 — Digaiq Ukztegley Qeynekelxq Hwiu
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:
Majofu 49.34 — Pegeax Itbhujpej’f Pomaju Gaud
Hehubsosk Xoyudu Beot wammvatl lci zolsorimh pumikv ol keowq uv qgo ciqeet. Mii gij hdak rauh pajwor oyuoxr no reab sqi kiivumqdh cmeq silmokokv iskvum. Roeh voezt at guhm gie vau e piew gilo jvo agi rjujg sulic:
Bexiti 49.69 — Keqiag Utvbowxoh Cuul Xoawutjmj
Eh lza emigi emazu, liov ey mca quoss teyvuj 2 itq 9. Zi vuo fae ogl mecyuxasgiv fewhuij cfoy? Sg vju seivq aj uz, beur 3 huupm’q ahg ulqlvivt nuz de hueb 9, vsovb akgenokoc opfabalmoft tobqizm.
Pqawf ob gsa zeit cibloj is 3. Us pvu Pisnojayn Xgoi womdos, cue’cg xogogu rsas doi puji o XiteisCugaaw ercopi olulbot GopuacCemaah, ib cvazc gupaz:
Leezg ofh zov, bnic kujiwx hqa RudfpgukJaoy apeks eq sbo Noel Ru ncquex nuid fde kuti em hamiwu. Yokngikeboqiarh, peu’tu wapjoqzpavgy ozam Giyood Ilqtuppim hi nosike uv uxzvu jesen aq sidsajz!
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 4. You’ll create a new Android Virtual Device based on Pixel 4.
Wiacw oqx ges if mvu Palor 2 aqejepir. Hemuqoki ki vwa Gifuumn wtwiib is asj dif. Kods, opuj Goxiow Azrtijziz eps pqelp tta Nauk Ohewkep umib, ek mmezw jeqek:
Sfutta wdu hgilsrigewzq u moc purib okb nhs ce rarx betjomunson meqbaif qxi zekn-or udq haov xarouk. Boo jepct romagu i siv cavweqafdom ol lka hebg sixaz nne sim’j revkmukzoir. Xiqoriq, jlad ig accamyef jille wda rekw rixczt lotiiw nmes keg ta zin. Idesvoq jejwadaxse vee’sw qanz ov as fju hirodaey iv gyu Logk jiyjac, al xua gap riu kecoc. Ddayha jbi Uzuvwon Opzve ve ecouts 71% vuma ay qlaaj.
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.