Utilizați jQuery Mobile pentru a crea o aplicație nativă Android Reader Partea 3

În Partea 1 a acestei serii de tutorial am prezentat aplicația noastră exemplară, am descris fluxul paginii și am discutat cum să construim paginile din aplicație prin jQuery Mobile. În Partea 2, am finalizat implementarea aplicației noastre web. În această ultimă parte, vom migra aplicația web într-o aplicație nativă Android.


Conversia într-o aplicație nativă Android

Aplicația web finalizată în Partea 2 va fi acum transformată într-o aplicație nativă Android. Discuția de mai jos se aplică sistemelor Android 2.2 și 2.3.

Aplicația Android va folosi index.html ca și componenta sa UI. Vom scrie un android.app.Activity clasa pentru a defini punctul de integrare între index.html și aplicația nativă. Vom scrie și noi android.webkit.WebViewClient pentru a vă asigura că pagina Detaliile pentru știri este afișată în interiorul originalului android.webkit.WebView exemplu în care este lansată aplicația Știri.

Schimbari in index.html

Vom actualiza NEWS_URI variabilă după cum urmează:

 var NEWS_URI = 'http://rss.news.yahoo.com/rss/';

Nu avem nevoie bridge.php în aplicația nativă Android pentru a trimite apeluri AJAX la Yahoo! Știri. Acest lucru se datorează faptului că restricția privind aceeași origine nu se aplică aici. Atunci când sunt ambalate ca parte a aplicației native, index.html fișierul nu este descărcat de pe un server web. Ca atare, poate face apeluri AJAX la adrese URL la distanță.

În plus, adăugăm următoarea funcție:

 var EMPTY = ";" schimbarea funcțieiLocation (varURI) showProgress (); $ .get (EMPTY, funcția (data) window.location = varURI;);

schimbă locația() funcția va fi apelată de la android.webkit.WebViewClient, care va fi afișat momentan. Scopul funcției este să afișați pagina de progres în timpul trecerii de la pagina Știri la pagina Detaliu știri.

  • Primul pas în schimbă locația() este să afișați pagina de progres.
  • Amintiți-vă că jQuery obține() funcția este o jQuery specializată ajax () funcţie. Noi sunam obține() transmiterea către el a unei adrese URL goale și a unui handler de apel invers, care stabilește window.location variabilă la argumentul de intrare. Argumentul de intrare este adresa URL din atributul inclus într - un A etichetă pentru o știre, după cum sa discutat în Partea 2, "Descoperirea paginii detaliilor de știri din pagina de știri". Când se încarcă adresa URL, pagina de progres este înlocuită cu conținutul din respectiva adresă URL.
  • Așa cum am arătat mai jos, funcția schimbă locația() nu este o parte esențială a migrării aplicației web într-o aplicație nativă. Este necesar doar afișarea unei pagini de progres atunci când treceți de la pagina Știri la pagina Detaliile știrilor din aplicația nativă.
  • O pagină de progres nu este necesară în aplicația web atunci când treceți de la pagina Știri la pagina Detaliile știrilor. Acest lucru se datorează faptului că, în timpul tranziției, browserul web afișează în sine un indicator de progres către utilizator. De exemplu, în Android, atât navigatoarele native, cât și browsele Dolphin afișează o roată de rotire și o bară de progres în bara de instrumente de navigare. În iOS, browserul Safari afișează un indicator de progres similar.

Clasa de activitate

Partea inițială a noastră Activitate clasa, numit NewsActivity este prezentat mai jos:

 pachet com.news; importă android.app.Activity; import șiroid.webkit.WebView; import android.os.Bundle ;? clasa publica NewsActivity extinde Activitatea WebView mWebView; public void onCreate (bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); mWebView = (WebView) findViewById (R.id.webview); mWebView.setWebViewClient (noul NewsClient ()); mWebView.getSettings () setJavaScriptEnabled (adevărat).; mWebView.getSettings () setDomStorageEnabled (adevărat).; mWebView.loadUrl ( "android_asset / www / index.html"); ? 
  • În onCreate () , vom numi mai întâi implementarea implicită din clasa super și apoi vom invoca setContentView () pentru a încărca fișierul de aspect pentru această activitate. Argumentul de intrare la setContentView () este R.layout.main care este o referință la main.xml în res / aspect pliant.
  • Avem un mâner pentru WebView prin intermediul findViewById (R.id.webview). Am stabilit un obicei WebViewClient pe WebView, numit NewsClient (pentru a fi revizuit în curând). Apoi, configuram WebView pentru a permite executarea JavaScript și API-ul de stocare DOM (acesta din urmă este necesar pentru a utiliza HTML5 localStorage).
  • În cele din urmă, cerem WebView pentru a încărca index.html care are codul UI.

În pagina Detaliu știri, apăsând butonul din spate al dispozitivului, utilizatorul va reveni la pagina Categorii. Pentru a fi sigur de asta, trebuie să ne ocupăm în primul rând de acest lucru onkeydown evenimentul nostru NewsActivity. Acest lucru este prezentat mai jos:

 clasa publica NewsActivity extinde Activitatea WebView mWebView; public void onCreate (Bundle savedInstanceState) ?  public boolean onKeyDown (int keyCode, eveniment KeyEvent) if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack ()) mWebView.goBack (); return true;  return super.onKeyDown (keyCode, event); ? 

Dacă evenimentul cheie corespunde cu butonul din spate al dispozitivului și WebView are istorie să se întoarcă, apoi întrebăm WebView să se întoarcă un singur pas în istoria sa. În pagina Detaliu de știri, aceasta va corespunde index.html. Când istoricul merge cu un pas înapoi, pagina Categorii va fi afișată urmând pașii descriși în Partea 2, "Punerea în aplicare a aplicației".

În cele din urmă, să ne uităm la obicei WebViewClient care este implementat ca o clasă interioară de NewsActivity.

 clasa publica NewsActivity extinde Activitatea WebView mWebView; public void onCreate (Bundle savedInstanceState) ? mWebView.setWebViewClient (noul NewsClient ());  boolean public onKeyDown (int keyCode, eveniment KeyEvent) ?  clasa privată NewsClient extinde WebViewClient public boolean shouldOverrideUrlLoading (vizualizare WebView, String url) view.loadUrl ("javascript: changeLocation (" + url + ")"); return true; ? 

Singura operație pe care o înlocuim din clasa parentală este shouldOverrideUrlLoading () unde instruim WebView pentru a apela funcția JavaScript schimbă locația() în index.html.

  • Nu am fi definit un obicei WebViewClient, pagina detaliilor de știri va fi afișată într-o aplicație de browser separată, în afara aplicației Știri. Prin urmare, definirea unui obicei WebViewClient este esențială pentru afișarea paginii Detaliile știrilor, ca parte a aplicației Știri (adică în același WebView care găzduiește index.html).
  • Am fi scris shouldOverrideUrlLoading () într-un mod mai simplificat, după cum urmează:
     public boolean shouldOverrideUrlLoading (vizualizare WebView, url de coarde) view.loadUrl (url); return true; 

    Acest lucru ar fi suficient pentru afișarea paginii Detaliile știrilor în același WebView care găzduiește index.html. Cu toate acestea, trecerea de la pagina de știri la pagina detaliilor de știri nu ar include afișarea paginii de progres.

După ce am examinat Activitate clasa, să ne uităm la alte componente ale aplicației noastre.

AndroidManifest.xml

            

Pentru o discuție generală despre AndroidManifest.xml dosar se referă la referința oficială. În acest dosar, există două elemente deosebite demne de comentat.

  • Așa cum este descris în android.app.Activity documentație, în mod implicit, o modificare a configurației, inclusiv o modificare a orientării sau a accesibilității tastaturii, duce la distrugerea activității curente. Pentru a preveni comportamentul implicit, configurați aplicația specificând modificările de configurare care vor fi gestionate de aplicația în sine. Acest lucru este definit în configChanges atributul unde orientare corespunde schimbării de orientare și keyboardHidden corespunde unei schimbări de accesibilitate a tastaturii (de exemplu, un utilizator deschide tastatura dispozitivului). Configuram aplicația astfel încât, dacă apare oricare dintre aceste modificări, activitatea curentă nu este distrusă.
  • Elementul permite aplicației să acceseze Internetul.

strings.xml

   Știri 

Acest fișier definește constanta numită numele aplicatiei care este folosit pentru a identifica aplicația News. Valoarea atributului respectiv este afișată în diverse locuri în dispozitivul nostru Android, după cum se arată mai jos. De la stânga la dreapta: sub pictograma de lansare a aplicației, bara de titlu a aplicației, Setări - Gestionați aplicațiile.

Figura 11. Cum este afișat numele aplicației în Android.

Integrarea interfeței UI pe bază de HTML cu android.app.Activity

Implementăm interfața utilizator în aplicația noastră nativă Android index.html și JavaScript și css biblioteci. Un punct de integrare între index.html și obiceiul android.app.Activity clasa este următoarea linie:

 mWebView.loadUrl ( "android_asset / www / index.html");

În plus, observați în "Clasa de activitate" că activați JavaScript și DOMStorage în android.webkit.WebView obiect ca index.html trebuie să ruleze JavaScript și să acceseze HTML5 localStorage.

 mWebView.getSettings () setJavaScriptEnabled (adevărat).; mWebView.getSettings () setDomStorageEnabled (adevărat).;

În cele din urmă, în AndroidManifest.xml permitem conectarea la Internet din aplicația noastră prin:

 

Imagini ecran ale aplicației Android

Figurile 1-4 din partea 1 a acestei serii sunt imaginile de pe ecran ale aplicației Android native.


Pictogramă de lansare a aplicației

Pentru a crea pictograma de lansare pentru aplicația News, am respectat regulile de proiectare a icoanelor pentru aplicațiile Android. În această resursă, diferite șabloane în format Adobe PSD sunt disponibile pentru descărcare. Am descărcat icon_templates-v2.0.zip și extrase Lansatorul-icon-template.psd. În acest fișier, am selectat două șabloane pentru a crea pictograma de lansare:

Am plasat aceste șabloane în două straturi separate în Adobe Photoshop și am adăugat un text grafic, Știri, pe un strat suplimentar din partea de sus pentru a compune pictograma de lansare. În funcție de orientare, am creat trei versiuni ale pictogramei pentru ecrane de joasă, medie și înaltă densitate, cu dimensiuni 36 x 36, 48 x 48 și respectiv 72 x 72 pixeli. Fiecare dintre aceste icoane este numită icon.png și sunt plasate în folderele de proiect Android conform tabelului următor:

Numele fisierului Nume de fișier Dimensiunea pixelilor
res \ drawable-ldpi icon.png 36 x 36
res \ drawable-mdpi icon.png 48 x 48
res \ drawable-hdpi icon.png 72 x 72

De exemplu, aceasta este pictograma de lansare 36 x 36:


Nativ mediul de dezvoltare a aplicațiilor Android

Ca parte a acestui tutorial, am furnizat fișierele de proiect necesare pentru a importa aplicația nativă Android News în mediul de dezvoltare Eclipse. Condițiile preliminare ale proiectului sunt:

  • Versiunea Android SDK 8.
  • Eclipse IDE versiunea 3.5.
  • Instrumente de dezvoltare Android (ADT), care este un plugin Eclipse, versiunea 8.0.1.

Proiectul a fost testat cu succes atât pe platforma Android 2.2 API nivel 8, cât și pe platforma API de nivel 2.3 API 9.

Importul Proiectului

Înainte de a importa proiectul în mediul Eclipse, asigurați-vă că pluginul Eclipse ADT indică locația corectă a SDK-ului Android în sistemul dvs. local. Pentru a verifica acest lucru, în meniul Eclipse mergeți la Fereastră -> Preferințe -> Android. Locația SDK fereastra trebuie să fie setată la locația SDK-ului Android. După configurarea corectă, ar trebui să vedeți ceva similar cu imaginea de mai jos:

Figura 12. Eclipse Preferințe.

Fișierele proiectului sunt furnizate într-un fișier de arhivă numit news.zip. Pentru a importa proiectul în meniul Eclipse, mergeți la Fișier -> Import apoi selectați din expertul de import fișier Generalități -> Proiecte existente în spațiul de lucru (Vezi mai jos).

Figura 13. Import de proiect.

În pagina următoare a expertului, alegeți Selectați fișierul de arhivă butonul radio și navigați către unde news.zip este localizat în sistemul dvs. de fișiere. proiecte fereastra va fi automat populate acolo unde Știri proiectul este deja selectat. Acest lucru este prezentat mai jos. apasă pe finalizarea pentru a finaliza importul.

Figura 14. Selectarea fișierului de proiect.

Eclipse va construi aplicația automat după import. Acum, ar trebui să vedeți proiectul Știri în exploratorul proiectului, după cum se arată mai jos:

Figura 15. Proiect Explorer.

Pentru construirea / depanarea proiectului, puteți alege între platformele Android OS 2.3 și 2.2 ca ținta de construire. Pentru aceasta, selectați Știri proiect în exploratorul de proiect și din meniul cu butonul din dreapta selectați Proprietăți. În lista de stânga a proprietăților, selectați Android ca proprietate. Obiectivele de construcție disponibile sunt afișate în partea dreaptă, după cum se arată mai jos:

Figura 16. Android Build Target.

Afișarea fișierelor

O listă a fișierelor din proiect este prezentată mai jos.

Figura 17. Conținutul proiectului.

Am discutat deja unele dintre aceste dosare. Mai jos este o scurtă recenzie / recapitulare:

  • src folder conține codul sursă pentru NewsActivity clasă.
  • gen folder conține fișierele generate automat de Eclipse ADT.
  • active \ www dosarul și subfolderele sale conțin toate fișierele necesare pentru interfața de utilizare, inclusiv index.html; active \ www \ css-js are css și fișierele JavaScript utilizate de către index.html. În special:
    • jquery-1.4.4.min.js, jquery.mobile-1.0a2.min.js, jquery.mobile-1.0a2.min.css sunt bibliotecile de framework jQuery Mobile.
    • jquery.ba-dotimeout.js este biblioteca jquery-dotimeout-plugin.
    • jquery.dst.js este biblioteca plugin DST.js.
    • active \ www \ css-js \ imagini \ icoane-18-white.png este un fișier imagine referit de bibliotecile de bază jQuery Mobile.
  • active \ www \ img \ wait.gif este pictograma de rotire utilizată în pagina de progres.
  • res \ drawable * folderele stochează icoanele de lansare, după cum sa discutat în secțiunea "Aplicație de lansare a pictogramelor" din acest tutorial.
  • res \ aspect \ main.xml fișierul este fișierul XML layout Android. Deoarece UI din aplicația noastră este definită în index.html utilizând cadrul jQuery Mobile, acest fișier este foarte simplu și nu are nevoie de explicații suplimentare.
  • Am revizuit deja res \ valori \ strings.xml și AndroidManifest.xml.
  • Fișierul default.properties definește obiectivul de construire și face parte din news.zip. Acesta va fi suprascris de Eclipse ADT în funcție de alegerea dvs. de a construi țintă.

concluzii

În plus față de dezvoltarea aplicațiilor web mobile pe mai multe platforme, cadrul jQuery Mobile poate fi folosit pentru a implementa aplicații native Android. În această serie de tutori am dezvoltat o aplicație web folosind jQuery Mobile și apoi am migrat-o într-o aplicație nativă Android cu doar mici modificări. Ideea principală este de a folosi android.webkit.WebView obiect ca un container pentru a rula fișierul html al aplicației web și codul jQuery Mobile JavaScript pe care îl conține. Unele observații finale sunt prezentate mai jos.

  • Atunci când este ambalat ca parte a unei aplicații Android native, o pagină html rulează în android.webkit.WebView nu este supus restricțiilor de aceeași origine atunci când efectuează apeluri AJAX.
  • Plugin-ul jquery-dotimeout și pluginul DST.js, deși inițial au fost dezvoltate pentru cadrul jQuery, funcționează bine pentru jQuery Mobile. Există o mare cantitate de plugin-uri scrise pentru jQuery și, deși este nevoie de o analiză de la caz la caz, acestea ar putea fi disponibile pentru jQuery Mobile. Acesta este un avantaj imens pentru acest nou cadru!
  • Am testat aplicația web cu un telefon Android OS 2.2 și un iPod Touch iOS 4.1 & 4.2. Aplicația Android nativă a fost testată cu ajutorul emulatorilor Android OS 2.2 & 2.3 și a unui telefon Android OS 2.2. În toate cazurile, atributele de aspect și simț și funcționale erau foarte asemănătoare.
  • În platforma Android, există tehnici cunoscute pentru a stabili apelurile metodologice Java-Java și Java-to-JavaScript. De fapt, am demonstrat cum să sunăm înapoi o funcție jQuery Mobile JavaScript din codul Java în aplicația noastră. Este posibil ca, cu un efort rezonabil, să se dezvolte pluginurile jQuery Mobile pentru a accesa API-urile Android. Acest lucru indică oportunități suplimentare pentru cadrul jQuery Mobile de a dezvolta aplicații native Android.
Cod