[MUSICA] Una delle caratteristiche distintive dei sistemi mobile moderni è che essi possono tenerci collegati in rete senza tenerci legati a una singola locazione. In questa lezione, esploreremo il software e le pratiche di programmazione che servono per collegare le applicazioni alla rete. Quindi inizierò questa lezione discutendo del networking in generale. Tale discussione si concentrerà sul collegamento delle app a Internet usando l'HyperText Transfer Protocol o HTTP, precisamente tramite richieste HTTP GET. Dopo di che, vi presenterò diverse classi che Android offre per supportare questo tipo di networking e infine, discuterò di come le applicazioni possono elaborare i dati ricevuti in risposta a queste richieste HTTP GET. In particolare, parlerò di due popolari linguaggi di formattazione dei dati. Uno, il JavaScript Object Notation Language, o JSON e due, l'Extensible Markup Language, o XML. E parlerò di come si analizzano, o si capiscono, queste risposte HTTP quando sono formattate in uno di questi linguaggi. Dunque, i primi dispositivi palmari ci hanno dato la mobilità. Ci si poteva spostare da un luogo all'altro, ed eseguire comunque computazioni utili. Tuttavia, le loro capacità di networking erano primitive per gli standard odierni. Ora, andando avanti, i dispositivi di oggi combinano potenti processori con veloci connessioni di rete via WiFi e reti cellulari. Le applicazioni portatili quindi vorranno spesso far uso di queste funzionalità di rete per accedere a dati e servizi e fornirne. Per aiutarvi a farlo, Android include una varietà di classi di supporto al netwoking tra cui le classi Socket e URL, nei package java.net, le classi HttpRequest e HttpResponse, nei package org.apache. E le classi URI, AndroidHttpClient, e AudioStream, nei package android.net. In questa lezione guarderemo molte di queste classi, usando ciascuna di esse per implementare la stessa applicazione di esempio. Quest'applicazione interagisce con un servizio internet per ottenere informazioni sui terremoti che si sono verificati in una particolare regione geografica. E come vedrete, quei dati vengono restituiti in vari formati. Inizialmente ci limiteremo a visualizzare il testo così come viene scaricato. Più avanti nella lezione, vi mostrerò come processare quei dati per estrarre solo le informazioni che volete. Oh, e un'altra cosa. Come si vedrà tra un momento, poiché questi dati includono informazioni geografiche, sarebbero più adatti ad essere mostrati su una mappa, piuttosto che come testo. Ora, non lo faremo in questa lezione, ma ricordatelo, perché ci ritorneremo quando arriveremo alla lezione su mappe e posizione. Per far funzionare quest'applicazione, il codice deve creare una richiesta http, inviarla a un server, recuperare i risultati, e quindi visualizzarli. Android fornisce molte classi per aiutare con questo. Tre di cui parleremo ora sono la classe Socket, la classe HttpUrlConnection e la classe AndroidHttpClient. Ora lancerò l'applicazione NetworkingSockets. Come potete vedere, quest'applicazione all'inizio visualizza un solo pulsante etichettato "Load Data" (Carica i Dati). Quando premo il pulsante, l'applicazione emette una richiesta HTTP GET a un server esterno, e quel server risponderà con del complesso che contiene i dati dei terremoti richiesti. Ok, quindi ora premo il pulsante "Load Data" e si possono vedere i dati richiesti. Diamo un'occhiata al codice sorgente per vedere cosa fa per ottenere i dati. Ora qui ho aperto l'applicazione nell'IDE. Ora aprirò l'Activity principale di questa applicazione, e qui sto mostrando il listener del tasto "Load Data". Quando si preme questo pulsante, l'applicazione crea, e quindi esegue, un AsyncTask chiamato HttpGetTask. Diamo un'occhiata a quella classe. La classe HttpGetTask dichiara in primo luogo alcune variabili, che vengono utilizzate nella creazione di una richiesta HTTP GET. Quando viene chiamato il metodo execute, sul HttpGetTask, viene chiamato il metodo doInBackground. E questo metodo inizia con la creazione di un nuovo Socket,che verrà connesso al computer host, api.geonames.org sulla porta HTTP standard, porta 80. Successivamente, il codice ottiene l'OutputStream del Socket, e quindi scrive l'HTTPGETCOMMAND, e questa stringa sarà inviata al computer host, che la interpreta come una HTTPGetRequest, e quindi risponde inviando i dati di risposta appropriati. Quindi questo codice continua ottenendo l'InputStream del Socket e passandolo a un metodo chiamato readStream. Il metodo readStream infine legge i dati di risposta dall'InputStream del Socket. e quindi restituisce la risposta come una singola stringa. E questa stringa viene passata al metodo onPostExecute che viene eseguito sul thread principale e che visualizza la risposta nella TextView. Torniamo all'applicazione. Si noterà che il testo di risposta include non solo i dati dei terremoti, ma anche gli header della risposta HTTP. Ora, di norma, non vorrei mostrare questo testo qui. Voglio solamente mostrare i dati dei terremoti. Quindi avrei dovuto analizzare la risposta ed estrarre solo i dati che volevo. Inoltre, potreste aver notato che non ho scritto alcun codice per la gestione di errori necessario per rendere quest'applicazione robusta. E questi punti catturano abbastanza bene gli svantaggi nell'usare i Socket. Il livello è molto basso, puoi scrivere qualsiasi cosa tu voglia sul socket, ma in cambio hai bisogno di gestire tutti i dettagli del fare le richieste HTTP, tutta la gestione degli errori, e tutto il processing delle risposte HTTP. La prossima implementazione che vedremo usa la classe HttpUrlConnection. Questa classe fornisce un'interfaccia di più alto livello, che gestisce più dettagli del networking rispetto alla classe Socket, ma come vedremo tra breve, ha anche una API meno flessibile della nostra ultima opzione, la classe AndroidHttpClient. Detto questo, voglio anche sottolineare che il team Android non sta più lavorando attivamente sulla classe AndroidHttpClient, e si sta concentrando sul miglioramento della classe che vedremo ora. Quindi guardiamo l'applicazione di esempio, implementata questa volta con la classe HttpUrlConnection. Ora lancio l'applicazione NetworkingURL. Come prima, quest'applicazione mostra inizialmente un singolo pulsante un singolo pulsante etichettato "Load Data" e come prima, quando premo quel pulsante l'applicazione emette una richiesta HTTP GET a un server esterno, e tale server risponderà con del testo complesso, contenente i dati richiesti sui terremoti. Ok, quindi ora premo il pulsante "Load Data". Si possono vedere i dati richiesti apparire in una TextView. Si noti, tuttavia, che stavolta gli header della risposta HTTP sono stati rimossi. Diamo un'occhiata al codice sorgente e vediamo come funziona. Ora, qui ho l'applicazione aperta nell'IDE. Ora apro la MainActivity di di quest'applicazione, e qui mostro il listener del pulsante "Load Data". Come prima, quando si preme questo tasto, l'applicazione crea e quindi esegue un AsyncTask chiamato HttpGetTask. Guardiamo quella classe. Quando il metodo execute viene chiamato su HttpGetTask, viene invocato il metodo doInBackground. Tale metodo inizia creando un nuovo oggetto URL e passando una stringa URL per il servizio desiderato come parametro. Il codice chiama quindi il metodo openConnection sull'oggetto URL, che restituisce una HttpUrlConnection. Quest'oggetto viene poi memorizzato in una variabile chiamata httpURLConnection. Il codice prosegue ottenendo l'InputStream della HttpUrlConnection e passandola al metodo readStream. E come prima, il metodo readStream legge i dati di risposta dal flusso di input del Socket, poi restituisce la risposta come una singola stringa. Questa volta, però, la HttpUrlConnection rimuove gli header della risposta HTTP e gestisce il controllo degli errori per te. Ora questa stringa viene quindi passata al metodo onPostExecute, che mostra la risposta in una TextView. La terza classe è AndroidHttpClient. Questa classe è un'implementazione del DefaultHttpClient del progetto Apache e permette una grande personalizzazione. In particolare, la classe divide la transazione HTTP in un oggetto richiesta e in un oggetto risposta. Quindi si possono creare sottoclassi che personalizzano la gestione delle richieste e delle loro risposte. Ora conoscete già l'aspetto dell'applicazione, quindi quindi saltiamo direttamente al codice ed esaminiamo l'implementazione. Ora, qui ho aperto l'applicazione NetworkingAndroidHttpClient nell'IDE. Ora apro la MainActivity di questa applicazione, e andiamo direttamente alla classe HttpGetTask. Tale classe inizia creando un nuovo oggetto AndroidHttpClient, chiamando il metodo newInstance della classe. Quando viene chiamato il metodo doInBackground, il codice crea un oggetto HttpGet, passando la stringa URL per quella richiesta. Quindi, crea un oggetto ResponseHandler. Quest'oggetto è responsabile della gestione della risposta alla richiesta HttpGet: in questo caso, il ResponseHandler è del tipo BasicResponseHandler, che restituirà il corpo della risposta. Vedremo un ResponseHandler più complesso più avanti in questa lezione. E, infine, la richiesta e il ResponseHandler vengono passati al metodo execute, che invia la richiesta e ottiene la risposta, passandola attraverso il ResponseHandler, e il risultato di tutto questo viene poi passato ad onPostExecute, che mostra la risposta in un campo di testo.