Sunteți pe pagina 1din 26

Android

- Noțiunea de Activity
 reprezinta o interfata cu utilizatorul, fereastra sau formular;
 o aplicatie Android poate avea una sau mai multe activitati; de exemplu o
aplicatie de tip Agenda poate avea o activitate pentru a gestiona contactele, o
activitate pentru a gestiona intâlniri si una pentru a edita o intrare in agenda;
 fiecare Activitate are propriul sau ciclu de viata, independent de ciclul de viata al
procesului asociat aplicatiei;
 fiecare activitate are propria stare si datele acesteia pot fi salvate sau restaurate;
 activitatile pot fi pornite de aplicatii diferite (daca este permis);
 are un ciclu de viata complex deoarece aplicatiile pot avea activitati multiple si
doar una este in prim-plan; utilizând managerul de activitati, sistemul Android
gestioneaza o stiva de activitati care se gasesc in diferite stari (pornire, in
executie, intrerupta, oprita, distrusa);
 in SDK, Activitatea este implementata folosind o subclasa a clasei Activity care
extinde clasa Context;

- Activity Lifecycle
Ciclului de viata al unei Activitati descrie starea in care o activitate poate fi la un
moment dat (denumirele sunt lasate intentionat in Engleza deoarece fac parte din
vocabularul programatorului):
Running - Activitatea a fost creata (onCreate()), pornita (onStart()) si este afisata pe
ecranul aparatului; in cazul in care activitatea a mai fost utilizata si aplicatia a salvat
starea acesteia (onSaveInstanceState()), activitatea este reluata din acel punct
(onRestoreInstanceState() si onResume()); in aceasta stare utilizatorul interactioneaza
cu activitatea prin intermediul interfetei dispozitivului (tastatura, touchscreen,
display);
Paused - Activitatea pierde prim-planul (onPause()), deoarece o alta activitate este
executata, cum ar fi o fereastra de dialog; de asemenea, in cazul in care aparatul intra
in modul sleep, activitatea este oprita temporar; activitatea isi poate relua executia
(onResume()) si este plasata inapoi in prim-plan;
Stopped – Activitatea nu este mai in uz si pentru ca este oprita (onStop()) nu este
vizibila; pentru a fi reactivata (ea deja exista), activitatea trebuie sa fi repornita
(onRestart() si onStart()) si reluata (onResume());
Destroyed – Activitatea este distrusa (onDestroy()) si memoria sa eliberat, deoarece
nu mai este necesara sau sistemul are nevoie de memorie suplimentara pentru rutinele
proprii sau pentru alte activitati; deoarece managementul memoriei este un aspect
important pentru sistemul de operare Linux al dispozitivului mobil, procesul care
gazduieste o activitate intrerupta, oprita sau distrusa, poate fi terminat pentru a elibera
memorie pentru noi activitati; doar procesele ce gestioneaza activitati ce ruleaza sunt
protejate;

- Process Lifecycle

onCreate(Bundle) – apelata cand activitatea este creata; folosind argumentul metodei


de tip Bundle exista posibilitatea sa restabiliti starea activitatii, care a fost salvata intr-
o sesiune anterioara; dupa ce activitatea a fost creata, va fi pornita (onStart());
onStart() – apelata in cazul in care activitatea urmeaza sa fie afisata; din acest punct,
activitatea poate veni in prim-plan (onResume()) sau ramane ascunsa in fundal
(onStop());
onRestoreInstanceState(Bundle) – apelata in cazul in care activitatea este
initializata cu datele dintr-o stare anterioara, ce a fost salvata; in mod implicit,
sistemul restaureaza starea interfetei cu utilizatorul (starea controalelor vizuale,
pozitia cursorului, etc);
onResume() – apelata cand activitatea este vizibila iar utilizatorul poate interactiona
cu aceasta; din aceasta stare, activitatea poate fi plasata in fundal, devenind intrerupta
(onPause());
onRestart() – apelata in cazul in care activitatea revine in prim-plan dintr-o stare
oprita (stopped); dupa aceasta, activitate este pornita (onStart()) din nou;
onPause() – apelata atunci când sistemul aduce in prim-plan o alta activitate;
activitatea curenta este mutata in fundal si mai târziu poate fi oprita (onStop()) sau
repornita si afisata (onResume()); acesta este un moment bun pentru a salva datele
aplicatiei intr-un mediu de stocare persistent (fisiere, baze de date) deoarece dupa
aceasta faza activitatea poate fi terminata si distrusa fara a se anunta acest lucru.
onSaveInstanceState(Bundle) – apelata pentru a salva starea curenta a activitatii; in
mod implicit, sistemul salveaza starea interfetei cu utilizatorul;
onStop() – apelata in cazul in care activitatea nu mai este utilizata si nu mai este
vizibila deoarece o alta activitate interactioneaza cu utilizatorul; din acest punct,
activitatea poate fi repornita (onRestart()) sau distrusa (onDestroy());
onDestroy() – apelata in cazul in care activitatea este distrusa, iar memoria sa
eliberata; acest lucru se poate intâmpla in cazul in care sistemul necesita mai multa
memorie sau daca programatorul termina explicit activitatea apeland
metoda finish() din clasa Activity;

- Structura Intent-lui

Intent (Intentie)
 reprezinta o entitate folosit pentru a descrie o operatiune care urmeaza sa fie
executata; este un mesaj transmis catre o alta componenta pentru a anunta o
operatiune;
 oarecum similar cu conceptul de event-handler din .NET sau Java.;
 un mesaj asincron utilizat pentru a activa activitati sau servicii;
 gestionata de o instanta a clasei Intent

Intent- mecanism de descriere a unei operațiuni (ex. alege fotografie, trimite


scrisoare, efectuare apel, deschide browser). Multe operațiuni în Android lucrează
prin intent.
Cele mai răspândite scenariile de utilizare a intent-urilor pentru a porni o altă
activitate în aplicația proprie. Dar acesta nu este singura variantă pentru utilizarea
intente-urilor. Ele pot fi utilizate pentru a anunța pornirea unui serviciu sau activități,
care sunt direcționate spre execuția unor acțiuni sau transmiterea unor notificări, care
atestă realizarea unui eveniment sau acțiune.
Intent-urile pot fi folosite pentru translarea mesajelor prin sistem. Fiecare aplicație
poate sa înregistreze un receptor de difuzare care urmărește intente-urile și posibilitatea
de a reacționa la ele. Aceasta permite crearea aplicațiilor ca folosește modelul de
evenimente, la baza căruia stă evenimentele interne de sistem sau evenimente externe,
care pot fi transmise prin programe externe.
Android poate transmite intent-ruri pentru a anunța despre evenimentele de sistem, de
exemplu despre modificările în starea conexiunii de rețea sau in nivelul de încărcare a
bateriei. Aplicațiile de sistem în Android, așa aplicații ca efectuarea apelurilor sau
controlul SMS, înregistrează componentele, care urmăresc intente-urile declarate, de
exemplu ai primit un mesaj SMS, și sistemul reacționează corespunzător la acest
eveniment.
Exemplu de cod pentru a trece de la o activitate la alta:
Intent intent = new Intent(HelloWorld.this, AboutActivity.class); startActivity(intent);
În intent se indică numele clasei (activitate) ca al 2 parametru. Această clasă trebuie
specificată în manifest, și sistemul parcurgând acest manifest ca porni activitatea
corespunzătoare. O aplicație poate avea mai multe activități, acestea pot fi apelate,
știind numele clasei. La trecerea dintr-o activitate în alta se poate specifica și ce date
ar putea fi transmise pentru prelucrarea lor în activitatea apelată. Pentru a efectua
această operațiune se utilizează metoda put…().
Exemplu de transfer a listei de fisiere dintr-o activitate in alta:

// У первой активности
ArrayList<File> fileList = new ArrayList<File>();
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("FILES_LIST", fileList);
startActivity(intent);
// У второй активности
ArrayList<File> filelist =
(ArrayList<File>)getIntent().getSerializableExtra("FILES_LIST");

Odată cu lucrul cu activități, cu date returnate, nu este posibilă utilizarea metodei


startActivit() deoarece aceasta returnează rezultat. Dacă este necesar returnarea
datelor se utilizează metoda stratActivityForResult(), care este adaptat pentru lucrul
cu apelurile.

În structura unei intenții pot fi identificate mai multe elemente, precizate în cadrul
secțiunii <intent-filter>, prin intermediul cărora se declară faptul că o componentă a
unei aplicații poate realiza o anumită acțiune pentru un anumit set de date (sau pe care
un ascultător al unei intenții cu difuzare îl poate procesa):
 acțiunea (action) care trebuie executată este indicată prin
proprietatea android:name, cele mai frecvent utilizate valori
fiind: MAIN, VIEW, DIAL, CALL, ANSWER, SEND, SENDTO, INSERT, E
DIT, DELETE, SEARCH, WEB_SEARCH; fiecare filtru de intenție trebuie să
indice cel puțin o acțiune; este recomandat să se utilizeze convențiile folosite în
Java pentru identificarea pachetelor pentru denumirile acțiunilor;
Între o acțiune și componenta pe care aceasta o invocă nu există o relație de tip 1:1,
întrucât o acțiune poate determina execuția unor componente diferite, în funcție de tipul
de date care sunt atașate acesteia. Astfel, fiecare activitate va defini ca atribute ale
alementului data din <intent-filter> informații legate de categoria MIME ale datelor
procesate (mimeType), de locația la care se găsesc (path, host, port), de schema utilizată
(scheme).
 categoria (category), indicată tot prin proprietatea android:name oferă
informații suplimentare cu privire la acțiunea care trebuie realizată; fiecare filtru
de intenție poate specifica mai multe categorii, putând fi utilizate valori definite
de utilizator sau valori preexistente în sistemul de operare Android:
 ALTERNATIVE - acțiunea ar trebui să fie disponibilă ca o alternativă la
activitatea implicită pentru tipul de date respectiv;
 SELECTED_ALTERNATIVE - acțiunea poate fi selectată, dintr-o listă, ca
o alternativă la activitatea implicită pentru tipul de date respectiv;
 BROWSABLE - indică o acțiune disponibilă din cadrul navigatorului;
pentru ca o activitate sau un serviciu să poată fi invocate din cadrul
navigatorului trebuie să specifice în mod obligatoriu această categorie;
 DEFAULT - utilizat pentru ca activitatea sau serviciul să fie utilizate în mod
implicit pentru tipul de date specificat în filtrul de intenții; de asemenea, este
necesar pentru activitățile sau serviciile care se doresc a fi lansate în execuție
prin intermediul unor intenții explicite;
 HOME - este folosit pentru a indica o alternativă la ecranul principal, dacă
nu este indicată nici o acțiune;
 LAUNCHER - atunci când este specificat, face ca activitatea să fie inclusă
în meniul de aplicații care pot fi lansate în execuție direct de către utilizator,
prin accesarea lor;
 alte
valori: INFO, PREFERENCE, CAR_DOCK, DESK_DOCK, CAR_MODE
, APP_MAKET.
 datele (data) reprezință informațiile care vor fi procesate, fiind exprimate de
obicei sub forma unui URI, fie că este vorba despre un număr de telefon
(prefixat de tel:), despre datele unei persoane din lista de contacte (prefixate
de content://contacts/people), despre coordonate geografice (prefixate de geo:)
sau o adresă Internet (prefixată de http://www.); pot fi specificate o serie de
proprietăți (în orice combinație) pentru a indica datele suportate de componenta
respectivă:
 android:host - o adresă (accesibilă prin rețea - poate fi indicată denumirea
sau adresa IP a gazdei) la care se găsesc datele ce pot fi procesate de
componentă;
 android:mimeType - tipul de date;
 android:path - locația la care se găsesc datele;
 android:port - portul pe care se permite conexiunea pentru accesarea datelor;
 android:scheme - un protocol prin intermediul căruia pot fi accesate datele
(spre exemplu, file, http, mailto, content, tel).
 tipul (type) referă în mod explicit clasificarea MIME al datelor (deși aceasta
poate fi dedus în mod automat din conținutul propriu-zis al datelor respective);
 componenta (component) specifică în mod explicit denumirea unei clase care
va fi invocată de intenție (deși aceasta putea fi dedusă în mod automat din
denumirea acțiunii și categoria ei, datele și tipul lor);
În situația în care se specifică un nume de componentă, intenția se numește explicită,
iar în situația în care aceasta este determinată în funcție de acțiune și de date, intenția
se numește implicită.
 extra (extra) este un obiect de tip Bundle care conține informații suplimentare
cu privire la componenta respectivă; informațiile conținute într-o intenție pot fi
obținute folosind intent.getExtras(), în timp ce specificarea unor informații care
vor fi atașate la o intenție va fi realizată printr-un apel al
metodei intent.putExtras(Bundle).

- Intent Resolution (Explicit Intent / Implicit Intent)

Sunt două tipuri de intenții(Intent):


 Explicit intents care specifică componenta(blocuri esențiale de creare a
aplicațiilor Android, ele sunt punctele prin care sistemul poate accesa
aplicația noastră, nu toate componentele sunt defapt puncte de intrare pentru
user și unele depind unele de altele, dar fiecare există ca o entitate anume și
joacă un rol specific și fiecare este un bloc de creare unic care ajută la
definirea comportamentului general al aplicației. Sunt 4 tipuri de
componente: Activity, Services, Content providers, broadcast recievers) care
începe cu un nume( numele clasei complet). Vom utiliza explicit intent pentru
a porni componenta în aplicația noastră, deoarece noi cunoaștem deja numele
activității sau serviciului ce o dorim să pornim. De exemplu: pornirea unei
noi activități ca răspuns la acțiunele unui user, sau pornirea unui serviciu
pentru descărcarea unui fișier în background.
 Implicit Intents nu denumesc o componentăă specifică dar în schimb declară
o acțiune generală ce trebuie de realizat care permite unei alte componente
din altă aplicație să se ocupe de ea. De exemplu: dacă se dorește afișarea unei
locații pe hartă al unui utilizator, putem să utilizăm un intent implicit de a face
apel la altă aplicație capabilă să specifice locația pe hartă.

Când creăm un intent explicit pentru a porni o activitate sau servicu, sistemul imediat
va porni componenta specificată în obiectul Intent.
Figura 1 : Are loc ilustrarea unui intent implicit și anume parcurgerea lui prin sistem
pentru a porni o altă activitate: [1] activitatea A crează un Intent cu acțiunea și o
trasmite la startActivity(). [2] sistemul android caută toate aplicațiile care corespund
intentului, atunci când aplicația necesară a fost găsită [3] sistemul startează activitate
potrivită (Activity B) invocând metoda onCreate() și transmite intent în ea.
Intent Resolution
Când sistemul recepționează intentul implicit pentru pornirea activității, el caută cea
mai bună activitate pentru inent, comparând intentul cu 3 aspecte de bază utilizând
Intent filtrul:
 Acțiunea intentului
 Datele intentului (ambele URI (Uniform Resource Identifier(Indentificatorul
universal al resurselor)) și tipuri de date)
 Categoria intentului

Secțiunele următoare vor descrie cum intenturile se potrivesc la cea mai apropiată
compoonentă cum filtrul intentului este declarat în fișierul Manifest al aplicației.
Exemplele ce urmează, vor găsi intentul potrivit utilizând intent filtrele:
Action test
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
...
</intent-filter>

Category test
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
...
</intent-filter>

Data test
<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http" ... />
<data android:mimeType="audio/mpeg" android:scheme="http" ... />
...
</intent-filter>
Exemplu de intent pentru a obține datele imaginii dintr-un content provider și să
le afișeze:
<intent-filter>
<data android:mimeType="image/*" />
...
</intent-filter>

Exemplu de intent pentru a obține datele unui video de pe web:


<intent-filter>
<data android:scheme="http" android:type="video/*" />
...
</intent-filter>

- Android Manifest

Fișierul Manifest AndroidManifest.xml reprezintă în format xml informația de bază


despre aplicație. Fiecare aplicație trebuie să aibă acest fișier. Redactarea fișierului se
poate efectua manual, schimbând codul XML sau schimbările pot fi efectuate prin
intermediul Manifest Editor, care permite să se realizeze redactarea vizuală și textuală
a fișierului în cadrul aplicației.
Particularitățile manifestului:
- Declararea numelui pachetului java, care reprezintă un identificator unic;
- Descrierea componentelor aplicației- activități, servicii, intent, care permit să fie
apelate clase, care realizează fiecare componentă, și declară intențiile lor;
- Conține lista permisiunilor necesare pentru apelarea interacțiunilor cu alte
aplicații;
- Declară permisiunile, care alte aplicații trebuie să le aibă pentru interacțiunea cu
componentele acestei aplicații;
- Declară nivelul minim API Android, necesar pentru lucrul cu aplicația;
- Enumeră biblioteci de legătură.

Structura manifestului:
Fișierul manifestului încapsulează toată arhitectura aplicației Android,
funcționalitățile și configurația acesteia. Elementele rădăcină ale manifestului
reprezintă <manifest>. Alte tag-uri importante și obligatorii sunt <application> și
<uses-sdk>. Elementul <application> reprezintă elementul de bază al manifestului
care conţine multe elemente descendente, care defines structura și lucrul aplicației.
Ordinea localizării elementelor, care se află la același nivel este arbitrar. Toate
valorile se stabilesc prin atributele elementelor.
Atribute:
- xmlns:android- definește namespace pentru Android, și niciodată nu se
schimbă;
- package- defineste numele unic al pachetului aplicatiei, care este definita
la etapa de creare a aplicatiei;
- android:versionCode- indica la numarul intern al versiunii, utilizind pentru
compararea versiunii aplicației;
- android:versionName- indica numarul versiunii de utilizare.
Exemplu concret de fișier AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mark.paiip2" >

<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORA
GE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".TwoActivity"
/>
</application>

</manifest>

-Noțiunea de Context

Cum sugerează numele, contextul reprezintă starea actuală(curentă) a


aplicației/obiectului. El permite obiectelor noi create să înțeleagă ce are loc. Noi îl
apelăm pentru a obține informația referitoare despre o altă parte a programului
(activity, package/application). Putem obține contextul invocând următoarele metode:
getApplicationContext(), getContext(), getBaseContext() sau this (când în clasa
activitate ).

Cazuri tipice de utilizare a contextului:

 Crearea obiectelor noi – este utilizată pentru a crea View-uri, adapters și


listeners:
TextView tv = new TextView(getContext());
ListAdapter adapter = new SimpleCursorAdapter(getApplicationContext(),
...);
 Accesarea resurselor standarde comune – servicii ca:
LAYOUT_INFLATER_SERVICE, SharedPreferences:
context.getSystemService(LAYOUT_INFLATER_SERVICE)
getApplicationContext().getSharedPreferences(*name*, *mode*);
 Accesarea implicită a componentelor – cea ce privește content providers,
intenturi și broadcasturi:
getApplicationContext().getContentResolver().query(uri, ...);

- Structura unui Serviciu

În Android, clasa android.app.Service este utilizată pentru componente a căror


funcționalitate implică procesări complexe, de lungă durată, necesitând acces la
anumite resurse, fără a fi necesar să pună la dispoziție o interfață grafică sau un
mecanism de interacțiune cu utilizatorul. Prin intermediul unui serviciu, se asigură
faptul că aplicația Android continuă să se găsească în execuție, chiar și atunci când
interfața grafică a acesteia nu este vizibilă.

Astfel, un serviciu nu trece prin evenimentele ce fac parte din ciclul de viață al unei
activități. Totuși, un serviciu poate fi controlat (pornit, oprit) din contextul altor
componente ale unei aplicații Android (activități, ascultători de intenții cu difuzare, alte
servicii).
Serviciul este rulat pe firul de execuție principal al aplicației Android. De aceea, în
situația în care operațiile pe care le realizează poate influența experiența utilizatorului,
acestea trebuie transferate pe alte fire de execuție din fundal (folosind
clasele HandlerThread sau AsyncTask).
Un serviciu continuă să se ruleze chiar și în situația în care componenta aplicației
Android care l-a invocat prin intermediul unei intenții devine inactivă (nu mai este
vizibilă) sau chiar este distrusă. Acest comportament este adecvat în situația în care
serviciul realizează operații de intrare/ieșire intensive, interacționează cu diverse
servicii accesibile prin intermediul rețelei sau cu furnizori de conținut.

Gestiunea unui Serviciu

Pentru a putea fi utilizat, orice serviciu trebuie să fie declarat în cadrul


fișierului AndroidManifest.xml, prin intermediul etichetei <service> în cadrul
elementului <application>. Eventual, se poate indica o permisiune necesară pentru
pornirea și oprirea serviciului, astfel încât aceste operații să poată fi realizate numai de
anumite aplicații Android.
<manifest ...>
<application ...>
<service
android:name="ro.pub.cs.systems.eim.lab05.SomeService"
android:enabled="true"
android:exported="true"

android:permission="ro.pub.cs.systems.eim.lab05.SOME_SERVICE_PERMISSION"
/>
</application>
</manifest>

- Runnable si Handlers (proprietati si mecanisme)

- Interfete si Clase Abstracte

Folosim o clasă abstractă atunci când vrem:

 sa implementăm doar unele din metodele din clasă


 ca respectiva clasă să nu poată fi instanțiată
Folosim o interfață atunci când vrem:

 să avem doar o descriere a structurii, fără implementări


 ca interfața în cauză să fie folosită împreună cu alte interfețe în contextul
moștenirii

Clase abstracte
Dorim să stabilim interfaţa comună pentru a putea crea funcţionalitate diferită pentru
fiecare subtip și pentru a ști ce anume au clasele derivate în comun. O clasă cu
caracteristicile enumerate mai sus se numește abstractă. Creăm o clasă abstractă
atunci când dorim să:

 manipulăm un set de clase printr-o interfaţă comună


 reutilizăm o serie metode si membrii din această clasă in clasele derivate.
Metodele suprascrise în clasele derivate vor fi apelate folosind dynamic binding (late
binding). Acesta este un mecanism prin care compilatorul, în momentul în care nu
poate determina implementarea unei metode în avans, lasă la latitudinea JVM-ului
(mașinii virtuale) alegerea implementării potrivite, în funcţie de tipul real al
obiectului. Această legare a implementării de numele metodei la momentul
execuţiei stă la baza polimorfismului. Nu există instanţe ale unei clase abstracte,
aceasta exprimând doar un punct de pornire pentru definirea unor instrumente reale.
De aceea, crearea unui obiect al unei clase abstracte este o eroare, compilatorul Java
semnalând acest fapt.

Metode abstracte
Pentru a exprima faptul că o metodă este abstractă (adică se declară doar interfaţa ei,
nu și implementarea), Java folosește cuvântul cheie abstract:

abstract void f();

O clasă care conţine metode abstracte este numită clasă abstractă. Dacă o clasă are
una sau mai multe metode abstracte atunci ea trebuie să conţină în definiţie
cuvântul abstract.

Exemplu:

abstract class Instrument {

...

Deoarece o clasă abstractă este incompletă (există metode care nu sunt definite),
crearea unui obiect de tipul clasei este împiedicată de compilator.

Interfeţe
Interfeţele duc conceptul abstract un pas mai departe. Se poate considera că o interfaţă
este o clasă abstractă pură: permite programatorului să stabilească o “formă” pentru
o clasă (numele metodelor, lista de argumente, valori întoarse), dar fară nicio
implementare. O interfaţă poate conţine câmpuri dar acestea sunt în mod
implicit static și final. Metodele declarate în interfață sunt în mod implicit public.
Interfaţa este folosită pentru a descrie un contract între clase: o clasă care
implementează o interfaţă va implementa metodele definite în interfaţă. Astfel orice
cod care folosește o anumită interfaţă știe ce metode pot fi apelate pentru aceasta.

Pentru a crea o interfaţă folosim cuvântul cheie interface în loc de class. La fel ca în
cazul claselor, interfaţa poate fi declarată public doar dacă este definită într-un fișier
cu același nume ca cel pe care îl dăm acesteia. Dacă o interfaţă nu este
declarată public atunci specificatorul ei de acces este package-private. Pentru a defini
o clasă care este conformă cu o interfaţă anume folosim cuvântul cheie implements.
Această relaţie este asemănătoare cu moștenirea, cu diferenţa că nu se moștenește
comportament, ci doar “interfaţa”. Pentru a defini o interfaţă care moștenește altă
interfaţă folosim cuvântul cheie extends. Dupa ce o interfaţă a fost implementată,
acea implementare devine o clasă obișnuită care poate fi extinsă prin moștenire.

Broadcast receiver
 o componenta care raspunde la anunturi difuzate (propagate) la nivel de sistem;
 oarecum similar cu conceptul de handler global (sau evenimente de sistem);
 implementata de o subclasa a clasei BroadcastReceiver.

Service (Serviciu)
 un task care se executa in fundal, fara interactiunea directa cu utilizatorul;
 gestionata de o instanta a clasei Service;

-Structura unei aplicatii android


O aplicație Android poate conține mai multe componente:

1. contextul reprezintă punctul central al unei aplicații Android, oferind acces către
mai multe funcționalități ale acesteia (inclusiv la resursele dizpozitivului mobil,
serviciile sistemului de operare, diferite fișiere de configurare); este instanțiat
sub forma unui obiect de tip android.app.Application;
2. activitatea realizează sarcini a căror execuție nu influențează timpul de răspuns
al aplicației Android, astfel încât să nu aibă un impact asupra experienței
utilizatorului; de aceea, este asociată unei ferestre (interfețe grafice), o aplicație
Android fiind formată din una sau mai multe activități;
3. fragmentul conține interfața grafică și logica aplicației corespunzătoare unei părți
din cadrul unei activități; motivul pentru care se recurge la modularizarea unei
activități prin intermediul a mai multor fragmente este asigurarea consistenței
și flexibilității aplicației Android pe mai multe echipamente mobile, cu
dispozitive de afișare de dimensiuni și rezoluții diferite;
4. serviciul încapsulează procese mai complexe, executate în fundal (și posibil la
intervale de timp regulate) a căror rulare durează o perioadă de timp
semnificativă, astfel încât să nu poată fi plasate în cadrul aceluiași fir de execuție
ca și interfața grafică prin care se asigură interacțiunea cu utilizatorul;
5. intenția este mecanismul de comunicare între elementele unei aplicații Android
(activități și servicii); prin intermediul unui sistem de mesagerie (asincronă),
sistemul de operare Android mapează o solicitare (împachetată sub forma unei
intenții) către componenta adecvată.

- Metode Asynchrone (async/await)

Odata cu C# 5.0 si .NET Framework 4.5, Microsoft a introdus in limbajul C# suport


pentru programarea asincrona prin cuvintele cheie async si await. Codul asincron
starteaza o operatie care se dasfasoara pe un termen mai lung si returneaza imediat
controlul thread-ului, fara a bloca cursul evenimentelor asteptand rezultatul operatiei.
Cand operatia s-a terminat, suntem notificati de acest lucru prin diverse mecanisme
cum ar fi un event, un delegate sau expresie lambda, await, etc. Exemple de operatii
"lungi" sunt accesul la diferite periferice, accesul la retea/internet sau diferite
intarzieri datorate unor procesari de date.
Microsoft marsaluieste tare pe programarea asincrona. Astfel, in Silverlight a eliminat
toate metodele sincrone din clasele care contineau ambele perechi, sincrone si
asincrone. Sub Windows 8 si .NET Framework 4.5, au fost deasemenea introduse o
serie de metode asincrone, insa au ramas si echivalentele lor sincrone. Microsoft
recomanda folosirea metodelor asincrone pe cat posibil, deoarece prin natura ei, o
aplicatie de tip Windows Store este terminata neasteptat, daca aceasta apeleaza o
metoda sincrona a carei timp de executie este foarte lung (de ordinul zecilor de
secunde).
Utilizarea perechii async/await a fost gandita astfel incat codul rezultat sa arate foarte
asemanator cu echivalentul sau sincron. In urmatorul exemplu voi prezenta o metoda
care descarca o pagina WEB si o afiseaza la consola.
private void PrintWebPage(string uri)
{
var client = new WebClient();
var page = client.DownloadString(uri);
Console.WriteLine(page);
}
Urmeaza echivalenta asincrona.
private async void PrintWebPageAsync(string uri)
{
var client = new WebClient();
var page = await client.DownloadStringTaskAsync(uri);
Console.WriteLine(page);
}
Se observa ca cele doua metode sunt foarte asemanatoare, diferenta constand in
"decorarea" celei de-a doua metode cu async si await si apelarea variantei asincrone
DownloadStringTaskAsync. Prin conventie, o metoda asincrona va contine sufixul
Async.
Aparent asemanatoare, cele doua metode sunt intern complet diferite. Compilatorul
C#, cand va intalni cuvantul cheie await, va imparti metoda in doua iar tot codul de
dupa await il va introduce in ce-a de-a doua parte/metoda. Putem verifica acest aspect
urmarind codul IL rezultat.La runtime, se executa codul pana se intalneste metoda
DownloadStringTaskAsync, dupa care se incepe descarcarea paginii dar nu pe thread-
ul curent. Thread-ul curent va preda controlul actiunilor utilizator, daca e un UI
thread, altfel resursele threadului vor fi eliberate.
De mentionat, ca await poate fi folosit doar in interiorul unei metode asincrone,
prefixata de async, dupa cum se poate vedea si-n exemplul de mai sus.O metoda
asincrona poate returna doar trei tipuri de date, si anume, void, Task si Task< T> unde
T poate fi orice fel de tip de date. Alte tipuri de date nu sunt permise deoarece
metodele asincrone nu blocheaza si au asociat un mecanism de notificare la
terminarea executiei metodei, care cunoaste doar cele trei tipuri de date ca rezultat.
Astfel, daca avem nevoie de o metoda care returneaza o valoare de tip int, atunci tipul
de retur al metodei asincrone ete Task< int> iar in corpul metodei vom avea la un
moment dat o declaratie de forma "return valoare_int;". Daca avem nevoie de o
metoda care nu returneaza nimic (void), atunci tipul de retur al metodei asincrone este
Task iar in corpul metodei vom avea la un moment dat o declaratie de forma "return;"
sau nimic (apelul return nu este obligatoriu).Exemplu:
private async void PrintWebPage1Async(string uri)
{
var client = new WebClient();
var page = await client.DownloadStringTaskAsync(uri);
Console.WriteLine(page);
}
private async Task PrintWebPage2Async(string uri)
{
var client = new WebClient();
var page = await client.DownloadStringTaskAsync(uri);
Console.WriteLine(page);
}

private async Task< string> GetWebPageAsync(string uri)


{
var client = new WebClient();
var page = await client.DownloadStringTaskAsync(uri);
return page;
}

- AsyncTask and Threads

Thread
De multe ori, aplicatiile au nevoie de mult timp pentru a rezolva o sarcina
(descarcarea unui fisier, printare, generarea unui raport etc), timp in care programul
nu poate raspunde unei alte actiuni a utilizatorului. Pentru a face ca o aplicatie sa
indeplineasca o sarcina si sa poata primi si altele in acelasi timp, sunt folosite firele de
executie multiple (multiple threads).
Intr-un program liniar se executa o singura linie de cod, se asteapta pentru completare
si apoi se continua cu urmatoarea linie de cod. Programul nu poate raspunde actiunii
unui utilizator in acest timp si chiar in cazul mai multor procesoare, va fi folosit doar
unul singur, limitand performanta, datorita programarii single-thread.
Un fir de executie (thread) este un program secvential, care poate fi executat
concurent cu alte fire. Un thread este o unitate de executie intr-un proces. Un proces
poate avea mai multe fire de executie, el numindu-se multithread. Daca un calculator
are mai multe procesoare sau un procesor cu mai multe nuclee, el poate executa mai
multe fire de executie simultan.
Diferenta dintre un proces si un thread este ca procesele sunt izolate total unul de
celalalt, in timp ce thread-urile impart aceeasi memorie (heap) cu alte thread-uri care
ruleaza in aceeasi aplicatie (un thread poate prelua informatii noi, in timp ce un alt
thread le prelucreaza pe cele existente).
Un fir de executie, thread, poate avea mai multe stari.

Task
Task reprezinta o operatie asincrona.
Task <T result> reprezinta o operatie asincrona ce returneaza o valoare, TResult.
Clasa Task <T result> este derivata din Task.
Instantele clasei Task pot fi create:
 Folosind proprietatea Factory ce returneaza o instanta pentru TaskFactory si
in continuare metoda SartNew.
 Foloseseste apelul metodei Start.

Cand cream un task ii furnizam un delegate ce contine codul ce se va executa.


Delegate-ul poate fi furnizat ca un delegate cu nume, metoda anonima sau o expresie
lambda. Expresiile lambda pot contine apel la metode cu nume (vezi si exemplul
anterior).
Observatie: In .NET 4.5 este implementata metoda Run in clasa Task.
Crearea unui Task se poate realiza urmarind mai multe scenarii.
Scenariul 1. Creare a unei instante a tipului Task urmat de apelul metodei Start().
var taskA = new Task(() => Console.WriteLine("Hello from taskA.")); //
Lansare taskA
taskA.Start();
Când se termină un fir de execuție:
O deosebita atenţie trebuie data modului in care un fir de execuţie se termina.
Terminarea unui fir de execuţie utilizând metoda stop() nu este recomandata, de altfel,
aceasta metoda este “deprecated” (nu mai este recomandată de către Sun pentru a fi
utilizată). Calea recomandata de terminare a unui fir este prin revenirea normala (
return ) din run(). Aşadar in cadrul metodei run se recomandă adăugarea unor blocuri
condiţinale care să determine terminarea firului de execuţie, respectiv ieşirea din
metoda run.
Acest mecanism nu este util de fiecare data deoarece in momentul in care un fir este
blocat ( datorita unor instrucţiuni wai(), sleep(), join(), operatii I/O ), acesta nu poate
verifica nici o condiţie. Pentru a termina un fir care este blocat se utilizează metoda
interrup(). Aceasta metoda determina aruncarea unei excepţii InterruptedException
care trebuie prinsa.
Exit code
ExitCode se foloseste pentru a obtine statutul unui process la terminarea lui. Puteti
utiliza ExitCodul ca o variabila integer pentru a returna o valoare dintr-o procedura. In
general serveste ca o variabila decizionala
WaitForSingleObject
Functia WaitForSingleObject verifica starea curenta a obiectului specificat. Daca
starea obiectului este nesemnalata, atunci firul de asteptare intra in stare de asteptare,
pina cind obiectul devine semnalizat sau intervalul de timp a depasit norma sa.
Functia WaitForSingleObject poate astepta urmatoarele obiecte: Change Notification;
Console input; Event; Mutex, Process, Thread etc.

- Protocolul HTTP

Hypertext Transfer Protocol (HTTP) este metoda cea mai des utilizată pentru
accesarea informațiilor în Internet care sunt păstrate pe servere World Wide Web.
Deseori utilizatorul dorește să transmită informații speciale la website. Aici HTTP
pune la dispozitie două posibilități:

 Transferul datelor în combinație cu o cerere pentru o resursă (HTTP-metoda "GET")


 Transferul datelor în combinație cu o cerere specială (HTTP-metoda "POST")
(Exemplu: la pagina de start de la Wikipedia.ro utilizatorul introduce în câmpul de
căutare termenul "pisici".. Atunci browserul trimite următoarea cerere la server:GET
/wiki/special:Search?search=pisici&go)
Erorile de HTTP sunt clasificate în 5 clase (categorii). Acestea sunt (pentru fiecare
clasa sunt date câteva dintre erorile conținute):
1xx - erori informaționale:
100 - contiunuă:
Utilizatorul ar trebui să își continue cererea/acțiunea. Acest răspuns provizoriu este
folosit pentru a informa utilizatorul că partea inițială a cererii a fost receptată și că
deocamdată nu a fost refuzată de server. Utilizatorul ar trebui să continue și să ignore
acest răspuns.
101 - schimbare protocol.
2xx - răspuns reușit: clasa de răspuns/status ce indică utilizatorului că cererea a fost
primită, înțeleasă și acceptată cu succes.
200 - ok:
Această cerere a fost executată cu succes. Informația a revenit cu un răspuns pozitiv,
indiferent de modul în care s-a făcut cererea.
202 - acceptat:
Cererea a fost acceptata pentru procesare, dar aceasta din urmă nu a fost terminată
complet. Scopul acestui mesaj este de a permite unui server să accepte cereri de la alți
utilizatori, fără a cere conexiunii clientului să insiste până ce procesul/cererea e
completă.

3xx - redirectări:
4xx - erori ale utilizatorilor: această clasă de mesaje/statusuri este folosită în
cazurile în care utilizatorul ar putea greși formularea cererii. Excepția fiind
răspunsurule pentru cererile tip „Direcționat/condus”, atunci serverul ar trebui să
conțină o intrare cu o explicație a situației erorii și dacă e o eroare temporară sau
pemanentă. Aceste răspunsuri sunt aplicabile pentru orice fel de cerere. Browser-ele
ar trebui să arate orice intrare cerută de utilizator.
400 - cerere greșită:
Cererea nu a putut fi înțeleasă/percepută de către server din cauza unei sintaxe
greșite/incomplete. Utilizatorul ar trebui să nu repete cererea fără ca aceasta să
suporte modificări.
401 - neautorizat
- Metodele și cîmpurile prot. HTTP

Câmpuri-mărimea pachetului, cookies


METODE
Metodele disponibile sunt :
GET: este cea mai folosită metodă, fiind utilizată atunci când serverului i se cere o
resursă.
HEAD: se comportă exact ca metoda GET, dar serverul returnează doar antetul
resursei, ceea ce permite clientului să inspecteze antetul resursei, fără a fi nevoit să
obțină și corpul resursei. Accesibilitatea resursei(desktop /mobile).
PUT: metoda este folosită pentru a depune documente pe server, fiind inversul
metodei GET.
POST: a fost proiectată pentru a trimite date de intrare către server.
DELETE: este opusul metodei PUT.
TRACE: este o metodă folosită de obicei pentru diagnosticare, putând da mai multe
informații despre traseul urmat de legătura HTTP, fiecare server proxy adăugându-și
semnătura în antetul Via.
OPTIONS: este folosită pentru identificarea capacităților serverului Web, înainte de a
face o cerere.
CONNECT: este o metodă folosită în general de serverele intermediare.

- XML/Json (metode de serializare/deserializare)

XML (eXtensible Markup Language), este un meta-limbaj utilizat in activitatea de


marcare structurala a documentelor. Documentele XML sunt realizate din unitati de
stocare numite entitati, ce contin date parsate sau neparsate. Datele parsate sunt
realizate din caractere, unele dintre ele formand date caracter iar altele ca marcaje.
Marcajele codifica o descriere a schemei de stocare a documentului si structura
logica. XML furnizeaza un mecanism pentru a impune constringeri asupra schemei
de stocare si a structurii logice.
Un document XML este format din marcaje (tag-uri) si date caracter.
Cuvantul marcaj (markup) a fost folosit initial pentru a descrie anumite adnotari,
note marginale in cadrul unui text cu intentia de a indica tehnoredactorului cum
trebuie listat un anumit pasaj. Generalizand, putem defini marcajul drept orice
actiune de a interpreta explicit o portiune de interpreta explicit o portiune de text.
Un marcaj (tag) este un sir de caractere delimitat de caracterele "<" si ">". Datele
caracterreprezinta continutul marcajelor.
În XML, marcajele nu sunt folosite pentru afisarea datelor continute, ci au alte scopuri
printre care:
● asigura o sintaxa simpla si standardizata pe care analizoarele XML o pot folosi
pentru a utiliza informatia stocata
● asigura o metoda de a descrie structura ierarhica a continutului prin impartirea
informatiei (datele caracter) in parti numite elemente care mai departe sunt
descrise prin atribute. Structura ierarhica a intregului document este pusa in
evidenta prin utilizarea marcajelor.
Un fisier XML cuprinde urmatoarele sectiuni:
● Prolog
● Definitia tipului de document (optionala)
● Elementul radacina

De ce folosim XML in Android in Layout


R/S:
- delimiteaza aplicatia in partea functionala de cea vizuala
- este usor de parsat
- este usor de citit pentru omanei
- consuma putina memorie
- un numar mare de IDE suporta formatul dat.

JSON este un acronim în limba engleză pentru JavaScript Object Notation, și este un
format de reprezentare și interschimb de date între aplicații informatice. Utilizat
pentru reprezentarea obiectelor și a altor structuri de date și este folosit în special
pentru a transmite date structurate prin rețea, procesul purtând numele de serializare.
In c# , seriaizarea are loc prin Json.NET - un popular JSon framework pentru .NET
Cea mai rapidă metodă de conversie dintre text și JSON obiect .NET utilizarea
metodei JsonSerializer.JsonSerializer convertește .NET obiecte în echivalentul lor
JSON si maparea obiect .NET, numele de proprietate la numele de proprietate JSON
și copii valorile pentru tine.
Deseralizarea reprezinta convertarea fisierului json In Obiecte.
Product product = new Product();

product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);

- notiuni generale și moduri de utilizare RegEx

Ea reprezintă o expresie regulată neschimbătoare.


Biblioteca : System.Text.RegularExpressions.Regex
Expresii regulate oferă un mod puternic, flexibil și eficient de manipulare a textlui .
Expresiile regulate ne permit să analizam rapid cantități mari de text pentru a găsi
modele de caractere specifice, verificați textul la template-uri predefinite (de exemplu,
e-mail, prelua, modifica, înlocui sau șterge subșir text.
Metode Utilizate:
1) IsMatch (String)
Indică dacă expresia regulată specificată în constructorul Regex găsește o potrivire
într-un șir de intrare specificat.
2) Replace(String,String)
Într-un șir de intrare specificat, înlocuiește toate siruri de caractere care se potrivesc
cu o expresie regulată specificat cu un șir de returnat de un string
3) Split (String, String)
Împarte un șir de intrare într-o serie de subsirurii de la pozițiile definite de un model
expresie regulată.
using System;
using System.Text.RegularExpressions;

class Program
{
static void Main()
{
Regex regex = new Regex(@"\d+");
Match match = regex.Match("Dot 55 Perls");
if (match.Success)
{
Console.WriteLine(match.Value);
}
}
}

Output
55

- HTML Parsing/xPath

XPath (XML Path Language) este un limbaj de expresii utilizat pentru a selecta
porţiuni dintr-un document XML sau pentru a calcula valori (şiruri de caractere,
numere, sau valori buleene) pe baza conţinutului unui document XML.Limbajul
XPath este structurat sub formă de arbore a documentului XML, oferind posibilitatea
de a naviga în acest arbore, prin selecţia nodurilor XML care satisfac diferite criterii.
Cea mai întâlnită metodă a expresiilor XPath este path expression. Un path expression
este scrisă ca o secvenţă de paşi pentru a ajunge dintr-un nod XML ('context node'-ul
curent) la un alt nod sau un alt set de noduri. Paşii sunt separaţi de caracterul "/" (ex.
path). Fiecare pas are trei componente:
• Specificatorul de axe
• Node Test
• Predicat

Parsarea HTML cu ajutorul Xpath ()/C#


Acesta este un parser HTML agil care construiește o citire / scriere DOM și sprijină
XPATH simplu sau XSLT Este o bibliotecă de cod .NET, care vă permite să elimine
"din web" fișiere HTML. Modelul obiect este foarte similar cu ceea ce propune
System.Xml, dar pentru documentele HTML (sau fluxuri). Html Agility Pack suportă
acum LINQ to Objects (printr-un LINQ în XML ca interfață). Exemple de aplicatii:
Fixare pagina sau generație. Puteți modifica o pagină așa cum doriți, modificați
DOM, adăugați noduri, copiați noduri, bine ... ce vrei tu. Scanere web. Puteți obține
cu ușurință la img / src sau a / hrefs cu un buchet interogări XPATH.
Exemplu
Sa presupunem ca avem un mic cod HTML numit LomakeTaustaVari;
{
HtmlAgilityPack.HtmlWeb web = new HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = web.Load
("https://www.op.fi/op/henkiloasiakkaat/saastot-ja-sijoitukset/kurssit-ja-
markkinat/markkinat?sivu=alltrades.html&sym=KNEBV.HSE&from=10:00&to=19:0
0&id=32453");

foreach (HtmlNode row in


doc.DocumentNode.SelectNodes("//tr[@class='LomakeTaustaVari']"))
{
Console.WriteLine(row.InnerText);
}
Console.ReadKey();
}
Exemplu 2
‹html›
‹head›
‹title›Test Html‹/title›
‹/head›
‹body›
‹span› This is span 1 ‹/span›
‹span› This is span 2 ‹/span›
‹span› This is span 3 ‹/span›
‹/body›
‹/html›
Codul următor oferă accesul la toate intervalele (Span) înăutru la pagina html
try{ HtmlDocument HD = new HtmlDocument();
HD.Load(new StringReader(rawHTML));
//rawHTML will contain the above HTML.
var SpanNodes = HD.DocumentNode.SelectNodes("//span");
//for details of XPath syntax see the above table, // operater returns
//all nodes matching the name after //. In above example it will return all
//span nodes.
if (SpanNodes != null) {
foreach(SpanNodes SN in HeadingNodes){
string text = SN.FirstChild.InnerText.Trim();
Console.WriteLine(text); //Will output all span's text } }
}catch(Exception e)
{ //Write your exception handling code here}

S-ar putea să vă placă și