Pentru a realiza aplicații pentru Android, trebuie instalat Android SDK. Acesta este compus din trei componente:
Pentru a face instalarea mai ușoară, Google oferă un pachet cu toate cele trei componente configurate. Acesta se numește ADT Bundle și se poate descărca de la adresa acesta. Fișierul este o arhivă zip, care conține două directoare: eclipse și sdk. În primul director se află editorul, iar în al doilea se află compilatorul, biblioteciile și simulatoarele de Android. În continuare, vom denumi SDK_ROOT directorul în care am dezarhivat ADT Bundle. Vom porni editorul Eclipse din SDK_ROOT/Eclipse/eclipse. În Windows, acesta se numește eclipse.exe. Odată pornit, va trebui să verificăm că avem instalate toate pachetele necesare. Pentru acesta, vom merge în eclipse, la meniul Window/Android SDK Manager. Verificăm să fie instalate următoarele:
Pe lângă aceste pachete, vom selecta pentru instalare următoatele:
Intel porteaza Android pentru platforma x86, aceeasi platforma folosita si pentru calculatoare. Din acest motiv, simulatorul pentru Android poate rula fara a fi nevoie sa simuleze platofrma hardware, insa are nevoie de imaginea Intel x86 Atom System Image si Intel x86 Emulation Accelerator(HAXM). Rularea programelor Android se poate face în două moduri: pe simulator, pe un telefon sau tabletă cu Android. Simulatorul pus la dispoziție de către Google este QEMU [2], care încarcă o imagine de Android. Pachetul de dezvoltare Android permite realizarea mai multor simulatoare. Pentru a le configura, vom merge in eclipse la meniul Window/Android Virtual Device Manager. Figura arată fereastra cu lista de simulatoare, aceasta fiind goală inițial. Vom apăsa butonul New… pentru a configura un nou simulator. În figura se pot vedea setările simulatorului. Setările sunt:
Pentru a rula pe telefon sau tabletă, este necesară activarea modului de dezvoltare pe acestea. În general, activarea se face de la Setări/Dezvoltare/Depanare USB. În Windows trebuie instalate și driver-ele telefonului sau tabletei. Acestea se pot obține de la producător.
Pentru a crea o aplicatie Android vom deschide Eclipse si vom selecta , dupa care vom selecta .
In urma acestor actiuni, va aparea fereastra urmatoare:
In campurile si se va introduce numele aplicatiei, iar in campul se va introduce numele pachetului care va contine aplicatia noastra. Este de preferat sa se introduca un text de forma .
Este de preferat sa se scrie site-ul in ordine inversa. Exemplu:ro.rosedu.android.Proiect1
In campul se va selecta versiunea de Android pentru care se creeaza proiectul, iar in campul se va selecta cea mai veche versiune de Android pe care poate rula aplicatia creata.
Structura unei aplicatii se poate observa din fereastra .
Pentru prima aplicatie vom utiliza un buton la a carui apasare va aparea un mesaj. Pentru a pune buton pe fereastra vom deschide fisierul . Fisierul este structura pe tag-uri, fiecare element reprezentand un tag. Pentru a adauga butonul, vom scrie urmatoarea bucata de cod:
<Button android:id="@+id/buton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Apasa" />
Pentru a adauga o actiune butonului, deschidem fisierul din directorul .
Vom crea o noua functie ce va fi apelata la apasarea butonului.
public void apasa(View v) { Toast.makeText(this, "Hello!", Toast.LENGTH_SHORT).show(); }
Pentru ca functia sa fie apelata la apasarea butonului, va trebui sa facem legatura intre buton si functie. Acest lucru se poate face in doua moduri: din codul programului sau din fisierul . Alegem cea de-a doua varianta, in care vom adauga urmatoarea linie in tag-ul butonului:
android:onClick="apasa"
Pentru a rula aplicatia, este necesar un simulator. Vom crea unul astfel: in Eclipse vom selecta
Apasam butonul New, introducem numele si versiunea de Android pe care o dorim, dupa care putem rula aplicatia.
Depanarea este foarte importanta in procesul de realizare a aplicatiilor pentru dispozitive mobile. Acest proces este insa putin diferit fata de depanarea programelor clasice pentru calculator, in primul rand pentru ca ruleaza pe alt dispozitiv. Tocmai din acest motiv, avem nevoie de programe spcializate pentru a realiza depanarea. De asemenea, fiind vorba de dispozitive mobile, apar si anumite evenimente specifice, cum ar fi apeluri telefonice, descarcarea bateriei etc., evenimente ce trebuie tratate intr-un fel sau altul. In laboratorul de astazi vom prezenta programele de depanare existente si modul lor de functionare. De asemenea, ne vom ocupa putin de studierea evenimentelor ferestrelor.
Utilitarul pentru depanarea aplicatiilor pentru Android se numeste DDMS (Dalvik Debug Monitor System). Acesta foloseste de fapt un alt utilitar, numit ADB (Android Debug Bridge), pentru a se conecta la simulatoare sau dispozitive fizice. Cu ajutorul DDMS putem vizualiza parametrii dispozitivului si a programelor ce ruleaza pe acesta. DDMS poate fi accesat sub forma unei perspective in Eclipse.
Activarea se face din meniul:
Window -> Open Perspective -> DDMS
Cele mai importrante functii pe care DDMS le poate indeplini sunt:
DDMS poate afisa informatii de depanare atat de la simulatoarele pornite cat si de la dispozitivele conectate la calculator. Alegerea dispozitivului curent se face prin selectarea lui din panoul Devices.
Logurile sistemului sunt cele mai importante informatii pe care le poate oferi DDMS. Aici sunt descrise toate actiunile indeplinite de catre dispozitiv, exceptiile aparute si informatii necesare depanaraii. Log-urile vor aparea in panoul denumit LogCat (a nu se confunda cu Console! - acestea sunt mesajele afisate de catre Eclipse). Fiecare mesaj din aceasta lista este insotit de urmatoarele date (fiecare pe cate o coloana):
Este de remarcat ca fiecare mesaj reprezinta cate o linie de text. Spre exemplu, exceptiile sunt in general afisate pe mai multe linii, acestea continand foarte multa informatie. Astfel, fiecare exceptie este reprezentata de mai multe mesaje de log.
Ceea ce ne intereseaza in continuare este cum putem genera astfel de mesaje de log. SDK-ul ne pune la dispozitie doua metode:
Exemplu pentru clasa //Log//: Log.println
(Log.DEBUG,
"exemplu
log",
"aceasta
este
un
mesaj
de
log
cu
eticheta
'exemplu
log'");
Exemplu pentru utilizarea System.out.println. De remarcat este ca mesajele de log trimise sub aceasta forma vor avea eticheta “System.out” si vor fi de tipul Information. System.out.println
("aceasta
este
un
mesaj
catre
consola
standard");
Un alta functie importanta ce trebuie discutata este posibilitatea de filtrare a mesajelor de log. Deoarece LogCat agrega toate mesajele de log din sistem, urmarirea unor anumite mesaje poate fi dificila. Pentru a usura aceasta sarcina, se pot genera filtre dupa:
Un filtru se creaza prin apasarea butonului plus verde din bara panoului Log (respectiv LogCat in Eclipse).
Desi destul de exact, simulatorul Android nu poate totusi simula functiile unui telefon real. Pentru a putea totusi testa comportamentul aplicatiilor cat mai bine, DDMS ne pune la dispozitie un panou de control (Emulator Control). Astfel putem sa simulam:
Evident, acest panou nou are nici un efect asupra dispozitivelor reale.
In panoul Threads sunt afisate informatiile despre fiecare fir de executie al fiecarui proces. Deoarece aceste informatii sunt culese prin intermediul unei legaturi de retea, overhead-ul este destul de mare. Pentru nu a incetini semnificativ functionarea dispozitivului (care este mereu nevoit sa trimita aceste date), vizualizarea trebuie activata. Astfel, se selecteaza procesul dorit (din panoul Devices) si se apasa butonul Update Threads. Dupa ce s-au cules informatiile dorite, monitorizarea se poate opri prin inca o apasare a butonului.
Un alt program foarte util pentru depanare este hierachyviewer. Acesta permite vizualizarea arborescenta a compozitiei fereastrelor. De asemenea afiseaza parametrii fiecarui View si timpul de incarcare al acestuia. O alta functie importanta este posibilitatea capturarii unei imagini a View-ului.
Trebuie mentionat ca putem analiza cu acest program orice aplicatie (componenta) ce ruleaza pe un dispozitiv. Ne putem astfel inspira asupra modului in care este construita interfata grafica.
Activarea se face din meniul:
Window
->
Open
Perspective
->
Hierarchy
Viewer
La fel ca DDMS, hierachyviewer functioneaza atat cu simulatoare cat si cu dispozitive reale. La pornire, este afisata lista dispozitivelor conectate. Se alege un dispozitiv (stanga) si o componenta ce ruleaza pe acel dispozitiv (dreapta) si se apasa butonul Load View Hierarchy. Daca nu s-a ales nici o componenta, programul va afisa componenta ce este in capatul Task-ului curent.
Afisarea ierarhiei de View-uri se face sub forma unui arbore avand alaturate fie propietatiile, fie imaginea fiecarui View. Selectarea intre cele doua moduri se face folosind butoanele de la baza ferestrei programului.
Vizualizarea ierarhiei impreuna cu imaginea ferestrei joaca un rol important in realizarea design-ului. Peste imaginea reala se poate suprapune o fotografie cu design-ul dorit. Fotografia suprapusa este semitransparenta, astfel permitand dezvoltatorilor sa faca corecturi asupra interfetei grafice, pana ce acesta se potriveste perfect cu design-ul.
Scopul acestui laborator este studierea evenimetelor ferestrelor utilizand programele de depanare descrise mai sus. Am discutat la curs despre evenimentele pe care le primesc ferestrele. Schema urmatoare le ilustreaza mai bine. Apelurile de functie sunt reprezentate in dreptunghiurile gri.
In continuare aveti ilustrat un exemplu de fereastra ce suprascrie toate functiile pentru evenimentele ce controleaza ciclul de viata. De remarcat este faptul ca fiecare dintre aceste functii face un apel catre functia parintelui (functie originala). Acest lucru este obligatoriu.
public class Evenimente extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onStart () { super.onStart(); } @Override public void onRestart () { super.onRestart(); } @Override public void onResume () { super.onResume(); } @Override public void onPause () { super.onPause(); } @Override public void onStop () { super.onStop(); } @Override public void onDestroy () { super.onDestroy(); } // functii folosite pentru salvarea si restaurarea starii @Override public void onSaveInstanceState (Bundle outState) { // apelarea functiei din activitatea parinte este recomandata, dar nu obligatorie super.onSaveInstanceState(outState); } @Override public void onRestoreInstanceState (Bundle inState) { // apelarea functiei din activitatea parinte este recomandata, dar nu obligatorie super.onRestoreInstanceState(inState); } }
Puteti observa in exemplul de mai sus ca trei dintre functii primesc ca parametru un obiect de tip Bundle. Acesta este folosit pentru memorarea starii in cazul in care activitatea trebuie inchisa din lipsa de memorie. Astfel, functiile sunt apelate in felul urmator:
Din obiectul de tip Bundle ne intereseaza cel mai mult functiile care incep cu put si functiile care incep cu get. Pentru anumite widget-uri(EditText, CheckBox) starea lor este salvata automat in //onSaveInstanceState//. Astfel, daca aplicatia este oprita(//onDestroy//), la repornire, un EditText va contine textul care a fost introdus anterior. Pentru a dezactiva aceasta optiune, putem introduce in fisierul xml, in tag-ul widget-ului dorit urmatoarea linie de cod: android:saveEnabled="false"
de asemea trebuie sa ii alocam un id widget-ului: android:id="@+id/idWidget"
Dezactiviarea se poate face si din cod folosind functia //setSaveEnabled(boolean).//