Android DDMS: un ghid pentru ultima consolă Android
Publicat: 2022-03-11Dezvoltarea este o afacere dificilă. Ținta continuă să se miște, noi tehnologii și domenii prind periodic viață, noi instrumente apar din când în când, iar limbile se schimbă în ceea ce pare a fi gestionat ravagii.
Totuși, chiar și cu toate aceste schimbări, regulile fundamentale rămân aceleași. Una dintre cele mai importante dintre aceste reguli de bază spune că, pentru a crea un software cu adevărat minunat, trebuie să obțineți o introspecție profundă, continuă și detaliată în sistemul dvs. de execuție. Diagnosticarea , depanarea și crearea de profiluri sunt termeni folosiți uneori în acest context, dar regula merge mai profund. Un dezvoltator de top „simte” literalmente sistemul său. El știe că ceea ce va cauza este o bucată de așteptare pentru eliberarea mai multor memorie, ceea ce va rula firele sale în lipsa procesorului, acțiuni care vor duce la I/O extins sau acces la rețea, prin urmare, va încetini întreaga sa funcționare.
Chiar nu există nicio cale de ocolire. Ați putea fi un dezvoltator foarte inteligent care scrie cod minunat, dar, până când nu veți avea abilitățile de mai sus, și anume să puteți monitoriza și studia detaliile comportamentului de rulare al sistemului dvs., veți eșua în continuare atunci când vine vorba de livrarea de top. aplicatii.
De fapt, după ce ai acumulat ceva experiență, vei detecta o întreagă categorie de „boli ale codurilor” care pot fi urmărite la neglijarea regulii introspecției: pe scurt, scrierea codului (uneori cod inteligent) fără monitorizarea continuă a efectelor sale asupra platformei actuale. .
DDMS în Android: Arma mea preferată pentru introspecție
Din fericire pentru noi, comunitatea Android a reușit să ofere atât de multe instrumente de introspecție de top. Stetho de la Facebook este printre cele mai bune, ARO de la AT&T ("Application Resource Optimizer") este ceva mai vechi, dar încă de top, cu probabil cea mai bună consolă de monitorizare a rețelei de acolo, în timp ce LeakCanary adoptă o abordare mult mai limitată concentrându-se (și se descurcă grozav la it) în biblioteca de detectare a scurgerilor de memorie în timpul rulării. Pe scurt, instrumentele de depanare Android nu lipsesc.
Cu toate acestea, diamantul din coroană, instrumentul de introspecție în care trebuie să aveți încredere atunci când trebuie extrase date cruciale, precise și bine formatate cu privire la comportamentul de rulare al aplicației dvs., este încă vechiul vechi Dalvik Debug Monitor Server (DDMS) din Android Studio, care a fost alături de noi (din păcate, subutilizat de atâtea echipe) încă de pe vremea pluginului Android Eclipse.
Cât de important este DDMS în dezvoltarea Android? Ei bine, știind ce știu acum despre DDMS și monitorizarea aplicațiilor mobile în general, spunem acum 5-6 ani, ca dezvoltator Android mai puțin experimentat, m-ar fi scutit de multe bătăi de cap și nopți de depanare.
Și lucrul este că DDMS este atât de simplu de stăpânit!
Desigur, o mare parte din utilizarea corectă, ca și în cazul oricărui alt instrument software, vine cu experiență. Trebuie să-ți perfecționezi abilitățile profesionale pentru o perioadă de timp, până când devii cu adevărat bun la monitorizarea performanței în timpul execuției. Dar chiar și în câteva ore, să spunem după ce ați citit acest articol, dacă urmați sugestiile mele și le aplicați pe următoarea aplicație, rezultatele vor fi uimitoare! Profilarea și reglarea chiar și a sistemelor complexe nu este atât de dificilă. Poate fi și distractiv!
Deseori se pune o întrebare cu privire la diferența dintre dezvoltatorii de telefonie mobilă începători și cei de master. Stăpânirea DDMS în Android – sau, în termeni generali, a capacităților de profilare a aplicațiilor și de introspecție – este una dintre aceste diferențe majore.
Notă: o parte importantă a devenirii unui dezvoltator de top este utilizarea celor mai bune biblioteci disponibile în domeniul dvs. Într-un articol anterior Toptal, am enumerat unele dintre cele mai bune biblioteci pentru dezvoltatori disponibile pentru Android. Într-un fel, acest articol este o continuare a articolului „bibliotecă” și acoperă unul dintre multele instrumente Android. Inutil să spun că, dacă doriți să vă îmbunătățiți abilitățile de dezvoltator Android, citiți-l acum!
Un ghid rapid pentru DDMS în Android Studio
Și acum, fără alte prelungiri, să ne adâncim acum în descrierea DDMS, unul dintre instrumentele finale pentru dezvoltatori Android.
Când cântăriți efortul și beneficiile, probabil niciun alt instrument nu vă poate îmbunătăți calitatea aplicației și vă poate ajuta să găsiți erorile cu adevărat dezordonate și evazive pe care le poate conține. Dar totuși, din anumite motive (lene, cineva?), atât de multe echipe nu reușesc să folosească DDMS.
Să începem cu un curs intensiv în DDMS:
DDMS este accesibil prin Studio > Instrumente > Android > Android Device Monitor și făcând clic pe butonul DDMS din meniu. De asemenea, puteți plasa ca pictogramă de comandă rapidă (eu) în panoul superior.
Odată deschis, iată ce veți vedea:
Panoul din stânga permite selectarea dispozitivului/aplicației, iar consola din dreapta vă oferă mai multe vizualizări, fiecare în propria filă, fiecare prezentând o vedere specifică a aplicației dvs.
Principalele servicii oferite de Dalvik Debug Monitor Server sunt:
- Statistici de utilizare a memoriei aplicației (statistici de alocare a heapului total și a obiectelor)
- Statistici fir de aplicație
- Captură de ecran a dispozitivului
- Explorator de fișiere de dispozitiv
- Falsificarea apelurilor primite și a SMS-urilor
- Falsificarea datelor de locație
- Logcat
Pentru a obține valoarea actuală a memoriei heap utilizată de aplicația dvs., faceți pur și simplu după cum urmează:
- Conectați dispozitivul pe care rulează aplicația dvs
- Faceți clic pe butonul Actualizare heap pentru a activa colectarea statisticilor heap
- Deschideți fila Heap
- Faceți clic pe „Cause GC” pentru a forța o rulare GC. Numai după o astfel de rulare va începe colectarea datelor heap
- Păstrați fila deschisă, continuați să lucrați la aplicația dvs. și faceți din nou clic periodic pe „Cause GC” pentru a reîmprospăta datele statisticilor heap
Această ultimă linie necesită probabil o explicație suplimentară. Utilizarea memoriei este una dintre acele valori analitice în care dinamica sa este mult mai importantă decât valoarea inițială. Pentru majoritatea aplicațiilor, nu ne va păsa prea mult de valoarea inițială de utilizare a heap-ului. Ne va păsa foarte mult de progresul acestei valori, deoarece ne va oferi o indicație clară a unuia dintre adevăratele coșmaruri care îi așteaptă pe dezvoltatorii de telefonie mobilă: scurgeri de memorie Android:
Utilizarea mea a modulului heap stat este simplă; ca parte a ciclului de viață al dezvoltării aplicației, după introducerea modificărilor care ar trebui să afecteze utilizarea heap-ului, voi activa modulul „Cause GC” pentru a iniția colectarea de statistici, voi activa (de obicei de mai multe ori) pozițiile intensive din heap ale aplicației mele, și periodic „Face GC” să se reîmprospăteze. Dacă utilizarea heap-ului continuă să crească, am o scurgere de memorie pe mâini și trebuie să o rezolv (detalii despre cum - mai jos). Dacă nu, și indiferent de dimensiunea reală a mormanului, sunt bine.
Dacă se detectează o scurgere de memorie, următorul instrument pe care îl voi folosi este Object Allocation Tracker. Să vedem ce poate face pentru gestionarea memoriei în Android.
Instrumentul de urmărire a alocării obiectelor
Instrumentul de urmărire a alocării, pur și simplu, vă va oferi informațiile necesare pentru a afla cine este partea care este „vinovat” pentru dimensiunea actuală a heap-ului. Acest modul vă va spune din ce fire și metode au provenit comenzile de alocare în timp real, făcându-l neprețuit pentru analiza memoriei în Android.
Pentru a începe urmărirea, procedați după cum urmează:
- Selectați dispozitivul/procesul relevant ca înainte
- Comutați la fila Alocation Tracker și faceți clic pe Start Tracking pentru a începe.
- De aici încolo vor fi urmărite toate noile alocări
- Faceți clic pe „Obțineți alocări” pentru a obține o listă cu toate cele mai recente alocări (cele mai recente de la ultimul „început”)
- Pentru a afla cine este autoritatea de alocare, faceți clic pe o anumită linie din listă
Acum, din propria mea experiență, efectuarea de acțiuni intensive de alocare în aplicația dvs., urmată de clic pe „Obțineți alocări” pentru a vedea contoarele de alocare, ar trebui de obicei să vă direcționeze către scurgere într-un mod simplu; uneori, fie atunci când scurgerea este neliniară (adică, se întâmplă din când în când) SAU când aplicația dvs. conține mai multe scurgeri care ar putea să nu funcționeze. În astfel de cazuri și nu am întâlnit multe dintre acestea, va trebui să recurgeți la crearea manuală a unui fișier HPROF de descărcare și analizarea acestuia. Analiza memoriei și gestionarea memoriei Android nu vor fi tratate în profunzime în acest articol. Vezi aici câteva piste.
Consola de informații despre subiect: Utilizarea procesorului Android este ușoară
Bine cunoscute oricărui dezvoltator, căile sincrone ale logicii de execuție sunt grupate în fire de execuție, fiecare alcătuind un singur flux de execuție în serie în cadrul aplicației dvs. Literal, toate aplicațiile folosesc mai mult de un singur fir de execuție. Unii dintre ei folosesc zeci.
O examinare de ansamblu a problemelor potențiale atunci când utilizați fire este cu mult în afara domeniului de aplicare al acestui articol. Să ne concentrăm apoi pe unul singur, și anume înfometarea firelor, care este principala problemă pentru care ați vizita consola de informații despre fire.
În toate aplicațiile mobile, fire diferite vor concura pentru timpul CPU. Pur și simplu nu sunt suficienți pentru a merge prin jur. Ce se întâmplă dacă, din orice motiv, unul sau mai multe fire de execuție nu vor obține timpul de execuție de care au nevoie? De obicei lucruri rele. Sistemul nu se va comporta așa cum ați planificat să se comporte, ceea ce este întotdeauna o idee proastă. Motivele potențiale ale acestei probleme ar putea fi setarea unei priorități scăzute, alte fire care se execută simultan setarea lor cu o prioritate prea mare, petrecerea mult timp pe monitoarele de sincronizare și multe altele. Toate sunt greu de detectat doar prin examinarea codului.
Consola de fir DDMS Android la salvare!
Pe măsură ce intrați în vizualizarea firului de discuție, veți vedea o listă formată din înregistrări ale firului de discuție, fiecare conținând numele și ID-ul firului de discuție, și două contoare suplimentare numite utime și stime. Utime măsoară timpul total petrecut de firul de execuție a codului utilizatorului (gândiți-vă la funcțiile dvs. și la bibliotecile de la terți), în timp ce stime măsoară timpul total petrecut cu codul de sistem (sleep, sincronizare, apeluri de sistem - mult). Prima — utime — va fi de obicei mai interesantă pentru noi, deși mă pot gândi la probleme care se vor manifesta în mare parte prin contorul de timp.
OK, avem codul în rulare, inclusiv mai multe fire și vrem să ne asigurăm că toate firele noastre primesc partea lor de timp CPU. Pentru aceasta, mai întâi lăsăm sistemul nostru să funcționeze pentru un timp, apoi deschidem fila fir și începem să căutăm valori de utime „peculiare”. Zero poate reprezenta cu siguranță o problemă – firul de execuție nu a primit literalmente timp de procesor și nicio utilizare a procesorului. Dar valorile prea mari ar putea reprezenta un aspect diferit al aceleiași probleme: și anume, firele a căror prioritate este atât de mare încât să îi provoace pe alții să moară de foame.
Rețineți că pentru un tip de fire, valoarea utime zero sau aproape zero nu va indica o problemă reală. Acestea sunt firele de execuție legate de I/O, fire de execuție care fac în mare parte acces la rețea sau la disc (sau baze de date). Aceste fire ar trebui să -și petreacă cea mai mare parte a timpului fie așteptând sosirea datelor, fie blocând apelurile de sistem în așteptare, niciuna dintre aceste acțiuni nu mărește contorul de timp. Cunoaște-ți firele!
Sfat: Nu utilizați niciodată numele implicit al firului de discuție. Nu înseamnă nimic și, de obicei, nu veți reuși să îl detectați în vizualizările DDMS. în schimb, ori de câte ori creați un fir de execuție sau îl preluați dintr-un grup de fire de execuție, începeți interacțiunea prin alocarea acestuia cu un nume explicit. Acest lucru vă va face viața mai ușoară decât depanarea/profilarea sistemului. De obicei, înaintez numele aplicației, astfel încât să fac distincția între firul generat de Android și cele generate de propriul meu cod, de exemplu: MyApp-server-connector, MyApp-db-interactor etc.

Sfat: Prioritatea unui thread denotă (în mod vag) cantitatea de timp CPU pe care o va acorda programatorul. Prioritatea atribuită thread-urilor dvs. de lucru este de o importanță critică pentru performanța generală și „netezimea” aplicației dvs. și, în multe cazuri, poate fi diferența dintre un comportament rapid rapid și unul lent accidentat. Regula aici este simplă: prioritatea implicită atribuită de Android, care este NORMAL=5, aproape întotdeauna nu este cea pe care doriți să o utilizați. În schimb, pentru majoritatea thread-urilor de lucru, doriți un impact mult mai mic asupra utilizării generale a procesorului. Pentru a face acest lucru, la pornirea unui thread, setați prioritatea la o valoare mai mică, de obicei merg cu priority=3.
Consola de statistici de rețea
Statisticile de rețea vă permit să monitorizați atât canalele de comunicare de intrare, cât și de ieșire către aplicația dvs. într-un mod rezonabil de citit de om.
Axa y din diagrama de rețea reprezintă viteza de transfer a transmisiei măsurată în KB/secundă, în timp ce axa x reprezintă timpul scurs în secunde. Prin urmare, pentru a obține o estimare rapidă a dimensiunii transmisiei, încercați să estimați aria vârfului relevant. După un timp, acest lucru devine destul de ușor.
Rețineți că, după ce ați introdus această consolă, va trebui să faceți clic pe butonul de sus „activare” pentru ca măsurătorile de rețea să înceapă să apară.
Înainte ca consola de rețea să se maturizeze la nivelul la care este acum, dezvoltatorii trebuiau de obicei să recurgă la utilizarea aplicațiilor sniffer (unii încă mai fac) pentru a obține informații similare.
Lucrul grozav la această consolă este modul în care vizualizează unul dintre comportamentele majore de descărcare a bateriei - acela al comunicării continue de dimensiuni mici a pachetelor. După cum mulți dintre voi știți, ceea ce va face din aplicația dvs. un consumator de baterie nu sunt cele cinci minute de rețea intensivă pe care le face, ci mai degrabă perioadele lungi de rețea scurtă și repetată, de exemplu, de dragul menținerii în viață, diagnosticării sau actualizărilor de stare.
Odată ce un astfel de model este detectat, iar afișarea vizuală a pachetelor de pe consola de rețea face totul atât de ușor, gândiți-vă imediat la lotizarea. Pot grupa mai multe transmisii mici într-una singură mare? Impactul acestei schimbări asupra bateriei este obligat să mute aplicațiile de la un consumator de baterie într-o categorie bine comportată!
Sfat: Nu încărcați niciodată o imagine în memorie așa cum este. Acesta este un accident fără memorie care așteaptă să se întâmple. În schimb, efectuați o încărcare redusă sau chiar mai bine, utilizați o bibliotecă terță parte pentru a gestiona scalarea pentru dvs.
Deși veți folosi rar aceste informații, rețineți că DDMS se bazează pe stiva Android Debug Bridge (ADB) pentru a transmite datele înapoi/de pe dispozitiv. Dacă DDMS nu reușește să vă afișeze aplicația sau se blochează în mijlocul unei sesiuni DDMS, cel mai bun pariu va fi să deschideți o consolă și să tastați:
adb devices
pentru a vă asigura că dispozitivul dvs. este accesibil și autorizat cu ADB. Dacă nu este cazul, în multe cazuri, repornirea serverului ADB local ar trebui să rezolve problema:
adb kill-server adb devices # restarts the adb server and displays all detected devices
Dacă întâmpinați în continuare probleme și aplicația dvs. este instalată pe un dispozitiv fizic, încercați să deconectați toate instanțele emulatorului. De ce? Deoarece DDMS se conectează atât la dispozitivele fizice, cât și la instanțele de emulator, implicită fiind cea din urmă.
Exemplu de utilizare DDMS în viața reală: o aplicație se oprește (nu se blochează, ci doar se oprește). Utilizatorul se grăbește imediat la stația de lucru din apropiere, se conectează la USB și deschide DDMS în vizualizarea firului pentru a afla stiva de fire » firul eșuat » urmărirea stivei — în cazul meu, din cauza blocajului de sincronizare care, odată detectat, a fost ușor de rezolvat prin comutare.
Sfat: dacă memoria RAM standard alocată aplicației dvs. de către Android nu este suficientă, așa cum s-ar putea întâmpla, de exemplu, în cazul aplicațiilor cu conținut media intensiv, rețineți că puteți obține aproximativ 15-20% memorie suplimentară pe majoritatea dispozitivelor prin ridicarea semnalului manifest _ largeHeap : https://developer.android.com/guide/topics/manifest/application-element.html_
Emularea stării dispozitivului în Android DDMS
De regulă, aplicațiile mobile nu sunt constructe liniare. În schimb, implementează strategii de conștientizare care le permit să monitorizeze și să reacționeze la schimbările în starea dispozitivului. O aplicație poate, de exemplu, să asculte apelurile primite sau mesajele text, își poate realinia starea în funcție de starea rețelei și poate urmări și reacționa la schimbările în locația dispozitivului.
Un exemplu banal pentru acesta din urmă ar fi o aplicație GPS. Cei mai mulți dintre noi nu dezvoltăm astfel de aplicații (din păcate, piața nu este suficient de mare...) dar totuși, în multe cazuri, implementăm logica, care depinde de locație, fie că este o simplă vizualizare pe hartă a poziției curente a utilizatorului, urmărirea rutei. , sau un afișaj de date sensibil la locație.
Testarea pentru astfel de condiții sensibile la stare este notoriu de complexă, uneori mai mult decât scrierea codului real. Dacă aveți un dispozitiv fizic cu SIM, puteți, desigur, să emiteți și să primiți apeluri și SMS-uri. Schimbarea stării de telefonie a dispozitivului este mult mai dificilă, dar totuși se poate face. Schimbarea locației de testare ar putea fi mai dificilă, deși o opțiune este să te plimbi prin oraș cu laptopul...
Dar totuși, cum ne-am gestiona instanțele de emulator? Cum le putem testa pentru aceste modificări?
DDMS la salvare, încă o dată. Una dintre caracteristicile mai puternice, dar adesea trecute cu vederea ale DDMS, este capacitatea sa de a lansa („falsificare”) evenimente simulate într-o instanță de emulator care rulează. DDMS poate emite un apel de la un anumit număr către emulator, poate trimite un SMS, poate modifica datele despre starea telefoniei și multe altele.
Odată ajunse în emulator, toate aceste evenimente falsificate nu vor mai fi distinse de evenimentele „reale”, adică, ca și cum ar fi primite de senzorii hardware de bază. Mai exact, toți receptorii aplicației dvs. relevante vor fi activați în același mod în care ar fi făcut-o la primirea unui apel real/un mesaj SMS.
Activarea stării și acțiunilor de telefonie este destul de simplă:
Pentru a testa aplicația pentru cazuri de conectivitate la rețea scăzută (ceea ce ar trebui să fie în orice aplicație centrată pe rețea), accesați secțiunea Stare telefonie și setați valorile vitezei și latenței la valorile dorite. De obicei, folosesc valoarea GPRS pentru ambele ca o modalitate eficientă de a emula conectivitate scăzută, dar nu ezitați să vă setați propriile valori.
Pentru a simula apeluri telefonice sau SMS, accesați secțiunea Acțiune telefonică, setați numărul de telefon de origine, adăugați un mesaj text dacă este necesar și trageți. Acest instrument este eficient în special atunci când ați setat o rută de cod dedicată pentru apelurile din străinătate și doriți să o testați la buget.
Lucrurile devin mai interesante când vine vorba de batjocorirea unei noi locații.
Dacă tot ceea ce vizați este să setați o nouă locație pentru instanța dvs. de emulator, alegeți Manual, setați valorile dorite de latitudine/longitudine și apăsați Trimitere.
Dar dacă, în loc să setați o locație fixă, doriți ca aplicația dvs. să treacă printr-o rută prestabilită - să zicem, să-i examinați comportamentul în timp ce utilizatorul călătorește dintr-un oraș în altul? Un astfel de test poate avea o mare valoare pentru orice aplicație bazată pe hartă, precum și pentru alte aplicații sensibile la locație, care își stabilesc fereastra de date pe locația utilizatorului. Aici, veți dori să vedeți că schimbarea locației cu viteză diferită va menține actualizată fereastra de date afișată.
Pentru aceasta, vom folosi un format special numit KML, care a fost dezvoltat special pentru a fi utilizat cu Google Earth și care reprezintă trasee, sau căi, ca un set de puncte conectate în spațiu, care poate fi de către dispozitive compatibile cu GPS.
GPX este un format alternativ de cale acceptat de DDMS. Pentru toate scopurile practice, acestea două ar trebui considerate interschimbabile atunci când sunt utilizate pentru falsificarea locației mobile.
Să trecem acum prin etapele stabilirii unei rute simulate în emulator.
- Creați un traseu. De departe, cel mai simplu mod ar fi să utilizați opțiunea de direcție Google Maps setarea originii și destinației corespunzătoare.
Odată ce traseul este afișat pe hartă, mergeți la linia de adresă și copiați adresa URL
Cu URL-ul în clipboard, accesați GPS Visualizer, inserați-l în caseta de text „Furnizați URL” și faceți clic pe butonul Convertiți:
și faceți clic pentru a descărca fișierul GPX rezultat (cu un nume oarecum dezordonat, de exemplu, 20170520030103-22192-data.gpx)
- Revenind la Controlul locației DDMS, deschideți fila GPX, faceți clic pe Încărcare GPX și selectați fișierul nou descărcat
- Au fost efectuate! Acum puteți naviga între diferitele locații ale rutei făcând clic pe butoanele înapoi și înainte sau făcând clic pe butonul Redare pentru a parcurge automat traseul la o viteză stabilită.
Nu trebuie să vă creați propriul traseu. O mulțime de rute de descărcat de pe site, cum ar fi OpenStreetMap (consultați secțiunea „Urmări GPS”).
În cele din urmă, vă rugăm să rețineți că, spre deosebire de versiunile DDMS mai vechi, în care încărcarea fișierelor de rută a fost ușoară, versiunile mai noi ar putea necesita unele încercări și erori la încărcarea unei anumite rute.
De exemplu, se pare că doar GPX 1.1 este acceptat de DDMS. Noile versiuni GPX ar putea necesita unele ajustări manuale.
În plus, formatul waypoint GPX nu mai este acceptat. În schimb, utilizați formatul GPX Track:
<trk> <name /> <cmt /> <trkseg> <trkpt lat="27.0512" lon="-80.4324"> <ele>0</ele> <time>2017-02-02T08:01:41Z</time> </trkpt> </trkseg> </trk>
Depanarea Android: o oră pe săptămână face diferența!
Ajunge teorie! Acum este timpul pentru puțină practică. Vă sugerez, presupunând că sunteți un dezvoltator Android, că, începând cu următorul proiect, veți dedica doar o oră pe săptămână pentru a obține introspecție în performanța aplicației dvs. prin DDMS.
Veți fi surprins de cantitatea de informații de calitate (adică, informații care pot fi folosite pentru a îmbunătăți imediat starea aplicației dvs.) pe care vi le va oferi!
Android DDMS, așa cum am văzut în repetate rânduri cu dezvoltatorii începători, este un instrument care poate îmbunătăți considerabil capacitățile unui dezvoltator, cu condiția să fie stăpânit și utilizat corespunzător. Capacitatea unui dezvoltator Android de a furniza sisteme de top va crește literalmente cu un pas sau două odată ce va atinge întregul potențial al DDMS în dezvoltarea Android. Prin urmare, alocarea de câteva ore pentru a folosi bine DDMS sună ca o investiție inteligentă, deoarece poate îmbunătăți considerabil performanța și eficiența Android.
Fii unul dintre băieții deștepți. Foloseste-l.