Când vine vorba de scrierea de aplicații mobile, este important să se integreze cu caracteristicile specifice platformei care sunt disponibile pentru dvs. când are sens. De exemplu, dacă ați scrie o aplicație de navigare, ar fi logic să utilizați funcțiile de localizare geografică a dispozitivului și a platformei. Dacă creați o aplicație pentru a ajuta persoanele cu deficiențe de vedere, ați dori să vă integrați cu orice funcții de redactare text la vorbire, care erau disponibile și ele.
Dezvoltatorii sunt cei care profită de aceste caracteristici care se fixează pe ei și aplicațiile lor în afară de restul. Aceste lucruri simple iau doar o aplicație obișnuită și o fac minunată. Dar ce se întâmplă atunci când doriți să profitați de aceste caracteristici, dar ați decis să adoptați Xamarin.Forms ca mecanismul tău inter-platformă de alegere? Trebuie să renunți la aceste caracteristici doar pentru că ați decis că aplicația dvs. trebuie să fie încrucișată și doriți să puteți împărtăși cât mai multă logică și cod de interfață utilizator? Absolut nu.
Aceste tipuri de întrebări provoacă inevitabil unele probleme pentru dezvoltatorii care adoptă tehnologii mai noi, cum ar fi Xamarin.Forms. Înainte de lansarea Xamarin.Forms, când lucrați direct cu șabloanele proiectului Xamarin.iOS, Xamarin.Android și Windows Phone, accesarea acestor tipuri de caracteristici a fost destul de simplă. Din perspectiva Xamarin, dacă ați putea găsi un exemplu C # - sau chiar o documentație nativă și o documentație SDK - pentru o anumită caracteristică, ați putea să vă cartografiați codul pe conceptele native, deoarece Xamarin a făcut o treabă atât de spectaculoasă de a traduce aceleași concepte native pe acele platforme în construcții de limbaj C #. Caracteristicile Windows Phone au fost și mai ușoare, deoarece nu a existat o traducere necesară. Tot ce trebuia să faci era să citești documentația.
Din fericire pentru noi ca dezvoltatori, Xamarin a pus mult timp și efort în proiectarea unui mecanism pentru a accesa aceleași caracteristici, chiar dacă alegem să le folosim stratul de abstractizare Xamarin.Forms. Acest mecanism este cunoscut ca DependencyService
.
DependencyService
Prezentare generalăLa prima vedere, un nume de genul DependencyService
poate părea puțin intimidantă. Suna ca o terminologie de programare fantezistă pe care doar câțiva elită înțeleg. Dacă ați lucrat vreodată Dependența de injecție (DI) sau Inversiunea controlerului (IoC), ar trebui să vă simțiți ca acasă cu DependencyService
. Dacă nu ați făcut-o, vă asigur că este un concept foarte simplu de înțeles când o descompuneți în componentele sale.
DependencyService
?La cel mai simplu lucru, DependencyService
este o clasă. Este o clasă a cărei unic scop de existență este să vă permiteți Inregistreaza-te orice număr de clase în întreaga aplicație. Prin înregistrare, vreau să iau orice clasă pe care o ai și să o informați serviciului. Odata ce DependencyService
știe despre o clasă, poate merge și poate recupera o instanță a clasei respective ori de câte ori este necesar. Acesta este celălalt scop al DependencyService
. Dacă în orice moment al cererii dvs. decideți că aveți nevoie de o instanță a unei clase care a fost înregistrată în DependencyService
, puteți solicita sau obține o instanță a acesteia.
Când te duci cu adevărat în jos în piulițele și bolțurile din DependencyService
, aceasta este o generalizare foarte largă. Dar din punctul de vedere al dezvoltatorului, asta e aproape tot ce trebuie să știți. Cu toate acestea, există un alt concept pe care trebuie să îl cunoașteți atunci când lucrați cu DependencyService
, interfețe. Când vine vorba de DependencyService
și toate acestea de înregistrare și de recuperare, de obicei, faci asta în ceea ce privește interfețele. Aceasta înseamnă că, atunci când înregistrați o clasă, o înregistrați ca o implementare a unei interfețe particulare. Și atunci când preiați o cursă, întrebați de fapt DependencyService
pentru implementarea interfeței respective. În acest moment, nu vă pasă ce este implementarea, doriți doar o clasă care să implementeze această interfață.
DependencyService
Muncă?Acum că aveți o înțelegere de bază la un nivel conceptual a ceea ce DependencyService
este, să săpăm puțin mai adânc și să vedem cum funcționează.
Pentru a utiliza DependencyService
, aveți nevoie de trei lucruri:
DependencyService
știți că o anumită clasă dorește să fie înregistrată și să poată fi recuperată mai târziu.DependencyService
, și solicită o anumită funcționalitate, o clasă, fără a trebui să instanțiate în mod direct o nouă instanță.Să aruncăm în fiecare dintre aceste concepte într-un mod mai detaliat.
Interfețele sunt întâlniri foarte frecvente în majoritatea limbilor de programare orientată pe obiecte (OOP) în aceste zile. Utilizarea unei interfețe vă permite să definiți un contract care conține o serie de proprietăți, metode, evenimente etc., care trebuie implementate de orice clasă care este de acord cu acel contract.
Iată un exemplu foarte simplu de interfață și o clasă care implementează acea interfață.
interfața publică IFileGrabber string GetFileContents (string fileUri); public SimpleGrabber: IFileGrabber șir public GetFileContents (string fileUri) returnează GetFileFromFileSystem (fileUri);
Acest lucru pare a fi un exemplu foarte simplu, dar servește scopului destul de bine. IFileGrabber
interfața definește o singură metodă, GetFileContents
. SimpleGrabber
clasa este de acord cu sau pune în aplicare IFileGrabber
interfață, ceea ce înseamnă că trebuie să conțină o implementare pentru o singură metodă.
Acum, în loc să trebuiască să implementați alt cod în aplicația dvs. direct împotriva unei clase concrete, SimpleGrabber
, puteți începe să faceți referire la IFileGrabber
interfață în loc. Imaginați-vă că aveți o altă clasă în aplicația dvs. care arată astfel:
clasa publica DataRetriever private IFileGrabber _fileGrabber; public DataRetriever (fișierul IFileGrabberGrabber) _fileGrabber = fileGrabber șirul public GetFileContents (string fileUri) return _fileGrabber.GetFileContents (fileUri);
Prin utilizarea funcției IFileGrabber
în locul unei clase concrete, aveți posibilitatea de a crea alte mecanisme pentru a prelua fișiere din diferite locuri și din DataRetriever
clasa nu ar pasa. Să presupunem că avem o altă clasă care arată astfel:
clasa publică NetworkGrabber: IFileGrabber șir public GetFileContents (string fileUri) returnează GetFileFromNetwork (fileUri);
Acum vă pasă mai puțin de modul în care clasa sau GetFileContents
metoda este implementată, știți doar că cel puțin membrii care sunt definiți în interfață sunt prezenți și asta înseamnă că puteți continua să codificați folosind doar acea interfață ca referință. Acesta este un concept incredibil de important atunci când este vorba despre DependencyService
.
În contextul DependencyService
, Xamarin a făcut procesul de înregistrare a unei clase destul de simplu. Deoarece deja ați definit interfața dvs. și cel puțin o clasă care o implementează, puteți să o înregistrați în DependencyService
folosind un atribut foarte simplu de asamblare.
Să continuăm să folosim exemplul de mai sus și să înregistrăm SimpleGrabber
clasă. Definiția de clasă ar arăta acum în felul următor:
[assembling: Xamarin.Forms.Dependency (typeof (SimpleFileGrabber)]] // orice declarație de spațiu de nume care poate exista public SimpleGrabber: IFileGrabber șir public GetFileContents (string fileUri) returnează GetFileFromFileSystem (fileUri);
Tot ce trebuie să faceți este să adăugați referința de asamblare deasupra definiției de clasă și în afara oricărei definiții de spațiu de nume care poate fi inclusă și în acel fișier. Făcând această sarcină simplă, veți fi înregistrat cu succes SimpleGrabber
clasa ca o punere în aplicare a IFileGrabber
interfață.
La înregistrarea unei clase, acea clasă trebuie să conțină un constructor fără parametru pentru ca DependencyService
să o instanțiați. În exemplul de mai sus, nu am definit un constructor, astfel încât compilatorul va crea, în mod implicit, un constructor fără parametri pentru mine.
Ultimul element al puzzle-ului este obținerea unui exemplu de clasă înregistrată. Aceasta este de fapt cea mai ușoară parte a întregului proces. Pentru a prelua o instanță a unei clase înregistrate, pur și simplu utilizați DependencyService
clasă și este generică Get <> ()
metodă. Iată un exemplu simplu:
public class FileHelper șir public GetFileContents (string fileUri) return DependencyService.Get() .GetFileContents (fileUri);
În acest caz, în timpul rulării, nu vă pasă unde DependencyService
este obtinerea de clasa de beton care implementeaza IFileGrabber
interfață. Tot ce vă interesează este că clasa implementează IFileGrabber
interfață.
DependencyService
Acum că aveți o înțelegere conceptuală a ceea ce DependencyService
este și cum să-l utilizați, să creați o aplicație simplă pentru a o utiliza.
Pentru acest exemplu, voi folosi Xamarin Studio 5, dar dacă doriți, utilizați Visual Studio 2013. Începeți prin a crea o soluție nouă. În Noua soluție caseta de dialog, în secțiunea C # din stânga, selectați Aplicații pentru mobil familia de proiecte. În partea dreaptă, selectați fie Aplicație Blank (Xamarin.Forms Portable) sau Aplicație Blank (Xamarin.Forms Shared) șablon de proiect. Codul și aplicația rezultată vor fi identice, indiferent de șablonul pe care îl alegeți.
În acest exemplu, voi folosi Biblioteca claselor portabile (PCL) a șablonului. Dați-i un nume proiectului. Voi numi soluția și primul proiect DependencyServiceSample. Apoi faceți clic pe O.K buton.
Acest proces va crea trei proiecte separate:
Studio Xamarin nu acceptă crearea de proiecte Windows Phone. Dacă utilizați Visual Studio, acest proces va crea patru proiecte. Acesta va crea cele trei proiecte de mai sus, precum și un proiect Windows Phone numit DependencyServiceSample.WinPhone.
În biblioteca partajată (DependencyServiceSample), creați un nou fișier de interfață și denumiți-l ISampleInterface și dați-i următoarea implementare:
namespace DependencyServiceSample interfață publică ISampleInterface string GetData ();
Acesta este un fișier de interfață cu aspect standard care definește o metodă simplă numită Obțineți date
care va reveni a şir
. Încă o dată, punctul important de înțeles este că, din perspectiva fișierului de cod partajat, nu-i pasă ce arată implementarea acestei interfețe. Singurul lucru care contează este că orice implementare este furnizată pentru această interfață, are o metodă numită Obțineți date
care va reveni a şir
.
Apoi, modificăm App.cs fișier pentru a utiliza DependencyService
pentru a obține o instanță a ISampleInterface
pentru a le utiliza în aplicația Xamarin.Forms. Modificați GetMainPage
metoda de a arata dupa cum urmeaza:
pagina statică publică GetMainPage () returnează ContentPage nou Content = new Label Text = DependencyService.Get(), .GetData (), VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.CenterAndExpand,,;
Observați că singura diferență este că Text
proprietate a Eticheta
a fost schimbat la următoarea linie:
DependencyService.Get().Obțineți date()
În acest fel, utilizați DependencyService
clasa și generic Get <> ()
- metoda de recuperare a punerii în aplicare a ISampleInterface
este implementat în proiectul specific platformei care este în curs de desfășurare. Odată ce acea instanță a fost preluată, îi sunați Obțineți date
metoda de a reveni la un șir și a seta Text
proprietate a Eticheta
.
Ultimul pas are două părți (trei dacă utilizați Visual Studio). În acest moment, va trebui să implementați ISampleInterface
interfață în toate proiectele specifice platformei în soluția dvs..
Să începem în DependencyServiceSample.Android cerere. Tot ce trebuie să faceți este să creați un nou fișier de clasă în proiect și să îi dați orice nume doriți. Am numit-o pe a mea Sample_Android. Înlocuiți implementarea implicită cu următoarele:
utilizând Sistemul; folosind DependencyServiceSample.Android; [assembling: Xamarin.Forms.Dependency (typeof (Sample_Android))] namespace DependencyServiceSample.Android clasa publică Sample_Android: ISampleInterface #region ISampleInterface implementare șir public GetData () return "Am venit de la proiectul Android!"; #endregion
Aceasta este o clasă simplă care implementează ISampleInterface
interfața și punerea sa în aplicare este de a returna pur și simplu a şir
declarând că vine de la proiectul Android. Singura diferență este utilizarea asamblare
atribut în partea de sus a fișierului că registre această clasă cu DependencyService
astfel încât să poată fi preluat mai târziu.
Acum, să realizăm o altă implementare a acestei interfețe în proiectul iOS. Creați o nouă clasă în proiectul iOS, denumiți-o Sample_iOS, și înlocuiți implementarea implicită cu următoarele:
utilizând Sistemul; utilizând DependencyServiceSample.iOS; [assembling: Xamarin.Forms.Dependency (typeof (Sample_iOS))] spațiu de nume DependencyServiceSample.iOS public class Sample_iOS: ISampleInterface #region ISampleInterface implementare șir public GetData () return "Am venit din proiectul iOS!"; #endregion
Implementarea este exact aceeași cu versiunea Android, cu excepția faptului că returnează un șir diferit, care afirmă că acesta vine de data aceasta de la proiectul iOS. Ultimul pas este să rulați aplicația și să vedeți dacă obțineți rezultatul pe care îl așteptați.
Iată rezultatul aplicației iOS care rulează.
Iată rezultatul aplicației Android care rulează.
După cum puteți vedea, ambele aplicații funcționează cu succes. Nu numai că rulează, dar rulează cu succes dintr-un proiect Xamarin.Forms partajat care controlează interfața cu utilizatorul. Din acest cod de interfață utilizator în cadrul Xamarin.Forms, acum puteți să vă imersați direct în proiectele specifice platformei pentru a accesa codul nativ.
Acum, că aveți abilitățile de a utiliza DependencyService
pentru a obține acces la funcționalitatea nativă din Xamarin.Forms, cerul este limita. Puteți continua să scrieți implementări simple, așa cum ați făcut în acest tutorial sau puteți începe să folosiți funcții mai interesante ale platformelor.
Una dintre cele mai interesante resurse pentru a vă uita la integrarea în dvs. DependencyService
este secțiunea Rețete a site-ului Xamarin. Aici veți găsi implementări specifice platformei de accesare a unui număr de funcții, inclusiv:
Toate aceste caracteristici vă stau la dispoziție atunci când vine vorba de aplicațiile Xamarin.Forms. Cu DependencyService
, aceste caracteristici pot fi convocate la un moment dat.
Acum că știți și înțelegeți DependencyService
, nu mai trebuie să vă simțiți intimidați atunci când aveți nevoie să accesați funcții specifice unei platforme dintr-o aplicație Xamarin.Forms. Acum posedați instrumentele care vă permit să atingeți acele caracteristici uimitoare ale dispozitivelor care vă vor permite în cele din urmă să vă diferențiați aplicațiile de celelalte în magazinele de aplicații.
Dacă doriți să aflați mai multe despre Xamarin, verificați cursul pe care l-ați construit Aplicații multi-platformă cu C # în Xamarin.
În curs, veți învăța cum să creați o aplicație cross-platformă dintr-o bază de cod unică, care va funcționa pe trei platforme diferite: iOS, Android și Windows Phone 8. Credeți că nu se poate face? În doar puțin timp o veți face singur. Sa trecem la treaba.
Puteți să o luați imediat cu un complet gratuit Studiu de 14 zile al unui abonament Tuts +. Aruncati o privire la optiunile noastre de abonament pentru a incepe sau, daca sunteti interesat doar de acest curs, o puteti cumpara individual pentru 15 $! Iată o previzualizare pentru a începe: