Documente Academic
Documente Profesional
Documente Cultură
1. Activity .................................................................................................................................................. 2
3. Process Lifecycle................................................................................................................................... 4
4. Structura intent-ului............................................................................................................................... 7
8. Noțiunea de View(Interfață)(Layout).................................................................................................. 12
1. Activity
În Android, o activitate reprezintă o fereastră care conține interfața grafică a aplicației. O aplicație poate
conține una sau mai multe activități (tipic, există măcar o activitate), scopul acestora fiind acela de a
interacționa cu utilizatorul. De obicei, o activitate implică un nivel de procesare redus astfel încât să se asigure
operarea aplicației în timp real. În cazul în care aplicația conține mai multe activități, navigarea între acestea
se realizează prin intermediul unor intenții (eng. intents), reținându-se pe stivă ferestrele anterioare, care se
găsesc în fundal. O singură fereastră poate interacționa cu utilizatorul la un moment dat. Activitatea care se
afișează la momentul în care se lansează aplicația desemnează ferastra principală, toate celelalte fiind accesate
prin intermediul acesteia. O activitate este reprezentată prin intermediul unei clase care extinde Activity.
Toate activitățile din cadrul unei aplicații Android trebuie să fie declarate în fișierul AndroidManifest.xml.
Se observă că pentru fiecare activitate trebuie să se precizeze clasa corespunzătoare (derivată din
Activity), distincția dintre fereastra principală și celelalte ferestre fiind realizată prin intermediul valorilor pe
care le iau elementele action și category din <intent-filter>. Pentru activitatea principală, acțiunea va fi
android.intent.action.MAIN, iar categoria android.intent.category.LAUNCHER (în sensul că această ferastră
va fi afișată în momentul în care se accesează pictograma aplicației din meniul telefonului), în timp ce pentru
celelalte activități se vor specifica valorile android.intent.action.VIEW, respectiv
android.intent.category.DEFAULT.
Scopul unei activități este de a interacționa cu utilizatorul. Din momentul în care activitatea apare pe ecran
și până la momentul în care dispare, ea trece printr-o serie de etape, cunoscute sub denumirea de ciclul de
viață al activității.
O activity apelează view-uri. View-urile sunt create in fisiere de tip xml, in care se pastreaza parametrii
layout-ului care se va afisa pe ecranul unui dispozitiv mobil. Sublasele unui View sunt Butoane, ListVew,
ImageView,RelativeLayout,LinearLayout etc. Activity poate fi de 7 tipuri, ele toate invoca o actiune
specifica.
Evenimentele activitatilor:
onCreate() - apelată în momentul în care activitatea este creată; această metodă va fi folosită pentru a
crea și pentru a instanția obiectele care vor fi utilizate în cadrul aplicației.
onStart() - apelată în momentul în care activitatea apare pe ecran
Toate componentele unei aplicații vor rula într-un singur proces și, în general, pentru majoritatea aplicațiilor nu este
nevoie de procese adiționale. Atunci când o aplicație pornește și nu are deja componente care rulează, Android va crea un
proces UNIX nou pentru acea aplicație care va conține un singur fir de execuție (thread). Toate componentele care vor porni
ulterior vor rula în acel thread, denumit și „main thread” sau „UI thread”. Vom discuta despre el mai jos, în detaliu.
Android are autoritate asupra proceselor care rulează și poate decide la un anumit moment să închidă un anumit proces
care poate fi chiar cel al aplicației noastre. Motivele pot varia, dar principala cauză are legătură cu memoria care poate deveni
insuficientă și este necesară eliberarea ei. În decizia de a opri un proces, Android ia în considerare mai multe aspecte, de
exemplu, dacă are sau nu componente vizibile pe ecran.
Procesele sunt încadrate în 5 nivele de importanță. Atunci când unele procese trebuie „omorâte”, cel cu nivelul mai mare
de importanță va fi „distrus” ultimul. Pe scurt, ele sunt:
1. Foreground Process
Un proces necesar pentru ceea ce utilizatorul face la un moment dat, de exemplu un activitycare e folosit de utilizator sau
un serviciu care e legat de activitatea cu care utilizatorul interacționează.
2. Visible Process
Un proces care nu are componente vizibile pe ecran, dar este necesar pentru componentele cu care interacționează
utilizatorul, cum ar fi un proces cu un activity care nu e în față, dar are un dialog pornit în prim-plan.
3. Service Process
Un proces care conține un serviciu și nu e esențial pentru ceea ce este afișat utilizatorului, cum ar fi un serviciu care redă
un MP3 în fundal în timp ce utilizatorul folosește alte aplicații.
4. Background Process
Un proces care conține o activitate care momentan nu e vizibilă utilizatorului. Pentru aceasta, există o listă LRU (least
recently used) care este luată în considerare în importanța unui proces.
5. Empty Process
Un proces care nu are componente active și este pornit doar din motive de caching sau pentru a îmbunătăți timpul de
start-up al unei aplicații.
Fire de execuție
Main Thread
Un proces poate avea mai multe fire de execuție. După cum am amintit mai sus, atunci când o aplicație e pornită, un
proces UNIX este creat, iar în cadrul lui – un singur thread. Acesta poartă denumirea de „main thread”. El este extrem de
important, pentru că este responsabil de interacțiunea cu utilizatorul, ca de exemplu lansarea de evenimente spre diferite
componente de UI (inclusiv partea de desenare) și este și firul în care aplicația interacționează cu componentele de UI.
Sistemul nu va crea thread-uri diferite pentru fiecare componentă. Ce înseamnă asta? Atunci când atingem un buton, acest
thread va lansa un eveniment de touch spre componenta respectivă care va lansa metoda responsabilă de schimbare a stării.
Fiind singurul thread responsabil de partea de UI, dacă aceasta este prea încărcată, poate avea o performanță slabă. Tot
din același motiv, acest thread trebuie ținut cât mai liber. Fiecare acțiune pe acest thread, mai ales cele de durată, îl vor bloca
și, implicit, aplicația nu va răspunde la acțiunile utilizatorului. Un exemplu în acest sens ar fi accesul la resurse de pe internet,
cum ar fi încărcarea unei poze. Dacă am lăsa ca încărcarea ei să fie făcută în acest thread, el ar fi blocat până s-ar finaliza
procesul de încărcare a pozei. Dacă poza este mare și conexiunea slabă, acest lucru poate dura câteva zeci de secunde. A ține
interfața blocată pentru un timp atât de lung nu este acceptabil.
De aceea, există două reguli de bază care nu sunt negociabile atunci când lucrăm cu componentele de UI și main thread-
ul:
Orice manipulare a interfeței de utilizator trebuie făcută din main thread, nu din thread-urile secundare.
Asynchronous Task
Există multe opțiuni pentru a folosi thread-uri secundare și a decongestiona main thread-ul: thread-uri clasice, servicii,
mecanismul de broadcast & receive. Una dintre aceste opțiuni este și mecanismul de asynchronous task. Acesta este
reprezentat de clasa AsyncTask și nu este nimic altceva decât un wrapper puternic parametrizat care oferă o serie de metode
specifice pentru a ușura interacțiunea dintre thread-ul secundar și main thread. În alți termeni, clasa AsyncTask este construită
ca și o clasă ajutătoare în jurul claselor Thread și Handler. Clasa e definită de un task care rulează pe un fir secundar în fundal
și care publică automat rezultatul spre main thread.
Pentru a crea un AsyncTask, trebuie să extindem clasa de bază AsyncTask care este definită de 3 tipuri generice, denumite
Params, Progress și Result și de 4 metode, dintre care una este obligatorie. Iată tipurile generice:
Dacă task-ul nostru are nevoie de parametri, aici trebuie specificat tipul lor. De exemplu, dacă task-ul ar trebui să
descarce o serie de fișiere, atunci tipul parametrilor ar putea fi URL sau String.
Dacă task-ul e de durată, este bine să informăm utilizatorul despre progresul făcut. În general, vom comunica o
valoare integer sau double, care specifică cât din task a fost efectuat, dar putem folosi orice fel de obiect dacă dorim să
trimitem informații complete. În cazul exemplului de mai sus, putem trimite ori o valoare care să reprezinte cât la sută din
toate fișierele de download a fost deja descărcat sau putem returna un obiect care să conțină și numele fișierelor deja
descărcate sau progresul individual pentru fiecare fișier în parte.
Dacă task-ul nostru nu folosește parametri de intrare, nu dorește să publice progresul efectuat sau pur și simplu nu va
returna nimic în urma procesării, putem folosi tipul Void.
Cele 4 metode pe care le oferă AsyncTask sunt fiecare dedicate unui pas din cadrul execuției unui task. Acestea sunt:
1. onPreExecute
Acest pas este executat înainte ca task-ul propriu-zis să înceapă execuția și este invocat în main thread. De obicei, îl
putem folosi pentru a pregăti execuția (ex: să afișăm un indicator de progres pe ecran).
2. doInBackground
Această metodă e invocată pe thread-ul de fundal imediat după onPreExecute și este metoda care execută task-ul propriu-
zis. Parametrii de intrare sunt trimiși acestei metode și ea va returna un obiect de tipul specificat pentru rezultat. În acestă
metodă, putem folosi și metodapublishProgress(Progress…), pentru a face public progresul făcut de task.
3. onProgressUpdate
Acestă metodă este invocată atunci când facem public un progres prinpublishProgress(Progress…) și o putem folosi
pentru a actualiza un progress bar sau pentru a scrie în log-uri. Ea se va executa în paralel cu task-ul din fundal.
4. onPostExecute
Acestă metodă este invocată pe main thread imediat ce task-ul de fundal este terminat și primește ca parametru obiectul
returnat dedoInBackground.
4. Structura intent-ului
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:
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.
Intenții nedefinite
Există la fel un tip de apelare a activității care la crearea unui intent nu se utilizează numele clasei, dar se
indică parametrii action, data category, cu anumite valori. Sistemul analizează acești parametri și alege
varianta corespunzătoare pentru a porni activitatea. De exemplu, dacă este indicată în parametri o adresă a
paginii web, atunci se presupune deschiderea browser-ului. Combinația dintre valori și parametri defineşte
scopul care vrem să-l atingem. Acestea pot fi accesarea unui link, trimiterea unei scrisori, apelarea unui număr
telefonic etc.
În filtrele intent-ului se pot utiliza parametrii action, data, category. Aceste tipuri de intent este un
mecanism care permite să trimiți cerere la componentele aplicației cu ajutorul activităților. La apelarea
metodei stratActivity(), creîn un astfel de tip de intent, trebuie de specificat activitatea, care trebuie să se
realizeze și la dorință o directorie URI la aceste date care trebuie prelucrate. La fel este posibilă transferul de
date adiționale în altă activitate, utilizând intent-ul extras. În acest caz pentru pornirea unei activități sistemul
singur va găsi clasa componentului necesar, care mai bine corespunde activității definite, luând în vedere tipul
de date.
Exemplu de creare a unui intent cu activitatea predefinită ACTION_VIEW pentru a porni browser-ul și de
a accesa adresa necesară:
ACTION_VIEW permite vizualizarea unei pagini web, în cazul dat. Odată cu declararea adresei (datele
necesare), se efectuează pornirea unei noi activități (browser-ul). În acest timp activitatea inițială lucrează ca
activitate de fundal. În fiecare caz Android singur găsește activitatea necesară pentru a răspunde la intent, și o
inițializează în caz de necesitate. Aplicația la fel poate crea intent-uri proprii pentru a permite altor aplicații să
le apeleze. Sistemul nu garantează prelucrarea intente-urilor.
Intent-ul conține informații care prezintă interes pentru Android, numele componentei care trebuie să-l
prelucreze intent-ul și setul de parametri pentru pornirea acestui component. Intent-ul conține următoarele
cîmpuri: ComponentName, activitatea, date (uri, mime), categoria, etc.
Pentru a accesa informații din intent se utilizează metoda getIntent(). Dacă intent-ul este nedefinit (ascuns)
atunci poți obține informații despre URL din intent la apelarea metodelor getAction(), getData(), getExtras().
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.
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>
6. 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" >
<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" />
</manifest>
7. Noțiunea de Context
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, ...);
Windows Phone
8. Noțiunea de View(Interfață)(Layout)
Interfața este procesul de redimensionare și poziționare a obiectelor în aplicația pe WP. Pentru a poziționa
obiectele vizuale, ele trebuie de pus în container de control derivat din Panel(rinduri sus la XML) sau alte
obiecte de tip container. WP oferă următoarele controale de panel: Canvas, StackPanel și Grid care servește ca
container și permite să poziționezi și să aranjezi controalele de pe ecran.
Sistemul de interfață al WP suportă atât interfață dinamică cât și absolută (Absolute/Dynamic Layout). În
interfața absolută controalele sunt poziționate utilizând explicit coordonatele X,Y (utilizând canvas). În
interfața dinamică UI al aplicației se redimensionează automat la diferite rezoluții a ecranelor dispozitivelor
(de exemplu: utilizând StackPanel sau Grid).
Panel controls
Panele interfeței incorporate in WP sunt: Canvas, StakPanel și Grid-ul.
Canvas
<Canvas Background="Transparent">
<Rectangle Canvas.Left="30" Canvas.Top="200"
Fill="red" Width="200" Height="200" />
</Canvas>
StackPanel
Este o interfață simplă care aranjează elementele descendente ale ei într-o singură linie care poate fi
orientată orizontal sau verticală. Pentru a specifica orientarea utilizăm proprietate orientation care arată
direcția descendenților. Exemplu (XAML):
<StackPanel Margin="20">
<Rectangle Fill="Red" Width="50" Height="50" Margin="5" />
<Rectangle Fill="Blue" Width="50" Height="50" Margin="5" />
<Rectangle Fill="Green" Width="50" Height="50" Margin="5" />
<Rectangle Fill="Purple" Width="50" Height="50" Margin="5" />
</StackPanel>
Grid
Permite poziționare flexibilă a elementelor pe ecran. El oferă posibilitatea de organiza elemente utilizând
coloane și rânduri. Se permite redimensionarea spațiului între o coloană sau un rând utilizând ”auto” sau ”*”.
Descendenții unui grid sunt desenați în ordinea în care ei apar în XAML sau cod. Exemplu (XAML):
Dacă vrem să creăm o interfață complexă care este greu de creat utilizând Canvas, StackPanel sau Grid,
putem crea panele custom, care permite să definim comportamentul interfeței pentru panela descendet. Pentru
a face acest lucru vom deriva din Panel și vom suprascrie metodele MeasureOverride și ArrangeOverride.
Extensible Application Markup Language este un limbaj markup declarativ. In mod specific, permite
initializarea de obiecte si setarea proprietatilor acestora, folosind o structura de limbaj ce descrie relatii
ierarhice intre obiecte. In timp ce fisierele XAML in sine permit crearea interfetei utilizator, intr-un mod
similar cu fisierele HTML, exista fisiere de cod, care corespund fiecarui fisier XAML, ce permit separarea
logicii de tratare a evenimentelor si manipulare a obiectelor ce constituie interfata grafica.
<Button Content="OK" Click="Button_Click_1" Background="Red" Foreground="Black"
Height="25" Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10"/>
XAML este de asemenea folosit si in Windows Presentation Foundation, iar acest lucru permite migrarea
eficienta a interfetei utilizator intre Silverlight si WPF. Totusi, este important de precizat ca Silverlight
foloseste doar un subset al vocabularului XAML care este disponibil in WPF.Fisierele XAML au intotdeauna
un singur element care serveste ca radacina, si acel element declara obiectul care va fi radacina conceptuala a
unei structuri, cum ar fi o pagina, sau graful de obiecte din timpul executiei aplicatiei.
Direct, folosind sintaxa obiect - element: se folosesc tag-uri de inchidere si deschidere "<" respectiv "/>"
pentru a instantia obiecte, intr-un stil ca si cel prezent in documentele XML. Se poate folosi aceasta
metoda pentru a declara obiecte radacina sau pentru a imbrica obiecte ce seteaza valorile proprietatilor.
Pentru convenienta, elementele ce nu mai contin alte elemente se pot inchide folosind "/>", fara a mai
defini un tag suplimentar. Exemplu:
<Grid>
<Rectangle/>
</Grid>
Indirect, folosind sintaxa atibut: se foloseste o valoare String inline, pentru a declara un obiect. Aceasta
metoda se poate folosi pentru a instantia orice alt obiect cu exceptia radacinii. Aceasta sintaxa este cel mai
adesea folosita pentru a seta valoarea unei proprietati. Pentru ca aceasta metoda sa functioneze, inseamna
ca tipul sau proprietatea setata suporta un convertor de tip care poate converti String-ul primit ca input,
sau ca parser-ul de XAML permite o conversie nativa. Cele doua exemple de mai jos produc un
dreptunghi de culoare albastra (rezultatul este la fel) :
sau
<Rectangle Name="rectangle1" Width="100" Height="100" Fill="Blue" />
Folosind extensii markup: Folosirea de extensii markup este asociata cu folosirea acoladelor "{" si "}"
pentru a indica folosirea extensiilor. Acest lucru permite parser-ului XAML sa evite tratarea valorii unui
atribut ca String-ul efectiv sau ca si rezultatul conversiei din string. Silverlight permite mai multe extensii
markup ce sunt definite sub namespace-ul XAML si sunt intelese de parser-ul XAML. Extensiile markup
sunt adesea folosite pentru Binding sau StaticResource (resurse definite de obicei altundeva) :
<Canvas.Resources>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="5"/>
</Style>
</Canvas.Resources>
...
<Border Style="{StaticResource PageBackground}">
...
</Border>
Moștenirea view-urilor (în XAML sus acolo sunt niște rânduri de ex. xmlns care reprezintă spații de
nume)
Spațiile de nume XAML aplică la un element specific în care ele au fost declarate și pe de altă parte
oricare element care se conține în acel element în structura XAML. Din cauza asta, spațiile de nume din
XAML sunt declarate aproape tot timpul pe elemente părinte care ie avantajele a conceptului de moștenire.
Un user control este compus din elemente existente. Adăugăm elemente în user control setând proprietatea
Content.
Exemplu (XAML):
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...>
Navigation controls
Text controls
List controls
HTML controls
Navigation controls
Aplicațiile WP sunt bazate pe pagini, în care utilizatorii navighează înainte sau înapoi prin diferite pagini a
contentului. Acest model este bazat pe frame-uri care conțin controalele paginii pentru a naviga prin aplicație.
Controale de navighare: PhoneApplicationFrame, PhoneApplicationPage.
Controalele interfeței sunt containere pentru alte controale și obiecte vizuale. Ele sunt utilizate pentru
poziționarea obiectelor vizuale pe ecran. Un control al interfeței servește ca interfață părinte a aplicației în
interiorul unei pagini. Restul obiectelor în UI se conțin în cest nod părinte. Majoritatea controalelor interfeței
derivă din clasa panel. Exemple de controale interfeței ce derivă din panel sunt: StackPanel, Canvas și Grid.
Mai există 2 controale adiționale: Panorama și Pivot, care le putem utiliza pentru a plasa aplicații pe
dispozitiv.
Controalele interfețelor și gruparea elementelor: Border, Canvas, ContentControl, Grid, Panorama, Pivot,
StackPanel, VirtualizingStackPanel, ScrollViewer.
Text controls
De obicei ele afiseaza contentul de tip string. In diferite procese dunt diferite controale. Controalele de
text in WP: TextBlock, TextBox, PasswordBox.
Afiseaza resursele, asa ca: imagini, mape si media contentul ce formeaza interfata aplicatiei WP.
Controalele sunt: Image, Map, MediaElement.
HTML controls
Tu poti utiliza controlul webBrowser-ului pentru a afisa HTML pagini in aplicatie. Exista doar un singur
control: WebBrowser.
Sunt utilizate pentru a reprezenta operatiile care se fac greu. Controalele sunt: ProgressBar, Popup.
Event listener - este o interfata a clasei View, ea contine o metoda ce contine un apel invers. Aceste
metode se vor apela de platforma Android, ca un rezultat al interacțiunii obiectului cu interfața utilizatorului,
se va activeaza obiectul afisat View, in care este inregistrat receptorul.
In exemplul de mai jos este prezentat cum de inregistrat un event listener pentru un buton (onClick)
// Create an anonymous implementation of OnClickListener private OnClickListener mCorkyListener =
new OnClickListener() {
public void onClick(View v) {
// do something when the button is clicked
}
};
protected void onCreate(Bundle savedValues) {
...
// Capture our button from layout
Button button = (Button)findViewById(R.id.corky);
// Register the onClick listener with the implementation above
button.setOnClickListener(mCorkyListener);
...}
General
12. 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.
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:
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).
Task
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).
Scenariul 1. Creare a unei instante a tipului Task urmat de apelul metodei Start().
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
14.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:
(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.
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.
401 - neautorizat:
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.
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.
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:
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.
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);
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
Î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
• Specificatorul de axe
• Node Test
• Predicat
Exemplu
{
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:00&id=32453");
Exemplu 2
‹html›
‹head›
‹title›Test Html‹/title›
‹/head›
‹body›
‹/body›
‹/html›
Codul următor oferă accesul la toate intervalele (Span) înăutru la pagina html
HD.Load(new StringReader(rawHTML));
//all nodes matching the name after //. In above example it will return all
//span nodes.
if (SpanNodes != null) {
foreach(SpanNodes SN in HeadingNodes){
}catch(Exception e)