ejercicio avanzado b - web services y ejecución en segundo plano

12
  Desarrollo de Aplicaciones Móviles en Android Ejercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas  personalizadas  Autores: Jorge Carballo Franquis David D. Harjani Harjani "#$%&' ( )* (+ Curso PUDE “Desarrollo de Aplicaciones Móviles en Android” Ejercicio Avanzado B: Web Services y Ejecución en Segundo  plano ,-&.-* /' 0*123 4%352 1-60'3 623'3 ' 72 7'8$2 )*7 6-8329 ':& .-*)' 1-602 ;28 )*36-<8%8= >&2 )* 723 $8'&)*3 -323 .-* 3* 7*3 )' ' 723 !"#$%&'()*! 9 *3 *7 )* -3-'8%23 )* 3*84%6%23 ?*<9 2 +*, .*$/01*!= @352 3* )*<* ' .-* 62&3%$-*& )'8 -&' &-*4' 4-*75' )* 5-*86' ' 723 3*84%6%23 .-* /' *A%35*& BC22$7* D*'8609 C22$7* E';39 F'6*<22G9 H?%%5*89 F7%6G89 "%6'3'9 I-28'9 *56=J @& *35* *K*86%6%29 4*8*123 -&' <8*4* %&582)-66%L& 32<8* 6L12 '66*)*8 ' *7723 )*3)* 7' ;7'5'M281' ,&)82%)=   !" #$%&'()&(*+ @7 $8'& '-$* )* 7' )*&21%&')' NO*< +=PQ *35# M-&)')' 32<8* 7' *A%35*&6%' )* 723 +*, .*$/01*!= @& *3*&6%'9 -& +*, .*$/01* *3 -& 1R52)2 )* 621-&%6'6%L& *&58* )23 )%3;23%5%423 *7*658L&%623 32<8* -&' 8*)= "'8' &23258239 )*3'88277')28*3 )* !"#$%&'()*! 9 3%$&%M%6' .-* 0'/ -&' 3*8%* )* 1#.-%&'3 62&*65')'3 ' S&5*8&*5 ' 7'3 6-'7*3 ;2)*123 8*'7%T'8 ;*5%6%2&*39 ;*5%6%2&*3 .-* 4274*8#& ' &2325823 *& M281' )* 8*3;-*35'3= H2)2 *352 3* <'3' *& 7' *A%35*&6%' )* -&' 3*8%* )* ;825262723 / *35#&)'8*3 BUHH"9 ODVW9 DX,"9 Y@DH9 Y"Z9 [EW9 \DX]9 *56=J ')*1#3 )* -&' $8'& 4'8%*)') )* 5*6&272$^'3 B,;'60*9 =]@HJ _"*829 .-R *3 72 .-* %1;285' '.-^` "8%1*829 )*<*123 *&5*&)*8 .-* 0'/ 4'8%'3 M281'3 )* 621-&%6'83* 62& -& 3*84%)289 )*;*&)%*&)2 )*7 ;82526272 .-* -5%7%6* R35* ;'8' 621-&%6'83* 62& *7 *A5*8%289 / 72 3*$-&)2 *3 .-* 7'3 621-&%6'6%2&*3 62& 3*84%6%23 ?*< *35#& <'3')'3 *& ,"S3= Z')' ;824**)28 )* 3*84%6%2 ?*< 5%*&* 3- ;82;%' ,"S9 / )*<%)2 ' .-* &23258239 723 )*3'88277')28*39 32123 -3-'8%23 )* *3'3 ,"S39 )*<*123 6-1;7%8 62& *77'39 / *35'8 '5*&523 ' ;23%<7*3 6'1<%23 ;28 ;'85* )* 723 '-528*39 ;28.-* 3% &29 72 ;'$'8#& &-*35823 -3-'8%23= ]23258239 *& *35* *K*86%6%29 77'1'8*123 ' 7' ,"S )* 62)%M%6'6%L& $*2$8#M%6' )* C22$7*= _]-*3582 2<K*5%42` "'3'87* -&' ;23%6%L& C"D BW'5%5-)9 W2&$%5-)J / .-* C22$7* &23 )%$' 6L12 3* 77'1' 7' 6'77* .-* 3* *&6-*&58' *& *3'3 6228)*&')'3=

Upload: jhonny-jair-gomez

Post on 16-Jul-2015

155 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 1/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página1de12

Curso PUDE

“Desarrollo de Aplicaciones Móviles en Android” 

Ejercicio Avanzado B: Web Services y Ejecución en Segundo

 plano

Aunque ya hemos visto muchas cosas a lo largo del curso, aún queda mucho por

descubrir. Uno de los grandesusos que se les da a los smartphones, es el de usuarios de

serviciosweb,oWebServices.Estosedebeaqueconsiguendarunanuevavueltadetuercaa

los serviciosque yaexisten (GoogleSearch,GoogleMaps, Facebook, Twiiter, Flickr, Picasa,

Quora,etc.) Eneste ejercicio, veremosunabreve introducción sobre cómo accedera ellos

desdelaplataformaAndroid.

 A. Descripción Elgranaugedeladenominada“Web2.0”estáfundadasobrelaexistenciadelosWeb

Services.Enesencia,unWebService es unmétodode comunicación entredosdispositivos

electrónicossobreunared.Paranosotros,desarrolladoresdesmartphones,significaquehay

una serie de máquinas conectadas a Internet a las cuales podemos realizar peticiones,

peticionesquevolveránanosotrosenformaderespuestas.

Todoestosebasaenlaexistenciadeunaseriedeprotocolosyestándares(HTTP,WSDL,SOAP,REST,RPC,XML,JSON,etc.)ademásdeunagranvariedaddetecnologías(Apache,.NET)¿Pero,

qué es lo que importa aquí? Primero, debemos entender que hay varias formas de

comunicarsecon un servidor,dependiendodelprotocolo queutiliceéstepara comunicarse

conelexterior,y losegundoesque lascomunicacionesconservicioswebestánbasadasen

APIs. Cada proveedor de servicio web tiene su propia API, y debido a que nosotros, los

desarrolladores,somosusuariosdeesasAPIs,debemoscumplirconellas,yestaratentosa

posiblescambiosporpartedelosautores,porquesino,lopagaránnuestrosusuarios.

Nosotros,enesteejercicio,llamaremosalaAPIdecodificacióngeográficadeGoogle.¿Nuestro

objetivo?PasarleunaposiciónGPS(Latitud,Longitud)yqueGooglenosdigacómosellamala

callequeseencuentraenesascoordenadas.

Page 2: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 2/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página2de12

 A.1.REST Al igual que SOA, REST es una arquitectura sobre la que pueden basarse losWeb

Services.Enesencia,RESTimplicaqueelservidornoposeeestado,esdecir,quecadapeticiónquehacemosalservidoresindependientedetodaslasanterioresydetodaslasposteriores;

nohaytokensnicookiesdepormedio.Estoescomúnenserviciosquenorequiereniniciode

sesión,comonuestrocaso,peroporejemplo,siquisiéramoscomunicarnosconFacebookpara

actualizarnuestroperfil,elfuncionamientoseríadiferente(tendríamosquemantenerelinicio

desesióncomountokenenestecaso)

REST,además,resultasermuysimple,puesposeeunnúmerofijodeoperacionesdefinidas

(GET,POST,PUTyDELETE),conunpropósitobiendefinidoporelprotocolo.GETseutilizapara

obteneralgúndato,POSTyPUTparasubir,modificaroañadiralgoalservidor,mientrasque

DELETE permiteeliminar undato del servidor. En lapráctica sinembargo,GETy POST son

ambosutilizadosparaobtenerdatos.Larazónesmuysimple;sialgunavezoshabéisfijadoen

lasdireccionesdevuestronavegador,habréisvistodireccionesenlasquealfinalhayparejas

(clave,valor)separadasporunampersand(‘&’);estasparejassonlosparámetrosquesele

pasanalservidor, ysiporejemplonecesitamosenviardatosprivados (por ejemplo:nuestra

dirección),no querríamosqueéstos navegaran abiertamente por la red. Por esta razón se

utilizaelPOSTcomoalternativaalGET,yaqueelPOSTpermiteenviarlosparámetroscomo

partede su cabecera (dentro del paquete), lo cual permiteesconder los datosunpoco, e

inclusodejaabiertalaposibilidaddeencriptarlosdatosyenviarlos.

Enlapráctica,lasoperacionesGET,POST,PUTyDELETEsonmuycomunes,ynotienenpor

quéceñirseaúnicamentealosserviciosdetipoREST;puedenserutilizadosporcualquierWeb

ServiceparaquelaAPIseamásfácildeentender,yparamantenerunciertoestándar.

B.  Implementación

ParacomunicarnosconlaAPIdeGooglenecesitaremosrealizarunapeticióndetipo

GET. En concreto, el servicio que vamos a utilizar es el de reverse-geocoding (codificación

geográficainversa),elcual nospermiteobtenerunadirecciónapartirdeunascoordenadasGPS. Para ello, nos bastará con una única Activity, un layout , y varios String.

Empecemos.

Nota: Para más información acerca de la API que estamos utilizando, visitar

http://code.google.com/intl/es-ES/apis/maps/documentation/geocoding/

Page 3: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 3/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página3de12

C.  Pasosaseguir

1.  ComenzamoscreandounnuevoproyectoAndroidparalaversión2.2(NOTA:Esteejerciciosiguesiendoperfectamenteválidoparaversionesanteriores),conel

nombrequequeramos,elpaquetequequeramosyasignándoleunnombreala

Activitypordefecto.

2. Antes de escribir el layout , necesitaremos definir una serie de etiquetas

(String):

3.  Paraellayout ,utilizaremosunRelativeLayoutcomopadre,quecomenzará

condosparejasdecombinacionesTextView/EditText(dosparesde

TextViewseguidosdeEditText).LosllamaremoslatitudeTV,latitudeET,longitudeTVylongitudeETrespectivamente.Todos

ocuparánlamínimaalturaposibleperotodoelanchoposible.Además,daremosacadaunounvalorasuatributotextenelordenenelqueseencuentran(latitudeylongitudeparalosTextView,defaultLatitudey

defaultLongitudeparalosEditText).ElprimerTextView(latitudeTV)hadeirancladoalapartesuperiordesupadre(android:layout_alignParentTop="true"),yelrestoseirácolocando

enordenjustodebajo(utilizarandroid:layout_below)A continuación colocaremos el Botón para accionar la petición; se llamarárequestButton, irá en la parte inferior del layout 

(android:layout_alignParentBottom="true"), y ocupará el mismo

espacioquelasViewanteriores.SutextoserálaetiquetagetAddress.

Para terminar con el layout , colocaremos otra pareja TextView/EditText

más:elTextViewdebeirbajoel EditTextlongitudeET,mientrasqueelEditText irá bajo el TextView que acabamos de añadir y sobre el

requestButton. El TextView ocupará el mismo espacio que los demás

(alturamínima,perotodoelanchoposible),mientrasqueelEditTextocupará

todo elespaciodisponible, tantoenancho como enalto.Además, nos interesaprepararlo para que soporte largas entradas de texto (ver atributosgravity,

inputType y scrollbars) Sus nombres serán resultTV y resultET

respectivamente.EltextoderesultTVdebesereldelaetiquetaresult.Por

último, este EditText no lo utilizaremos para introducir datos, sino para

  <string name="latitude">Latitud: </string> <string name="defaultLatitude">28.482566</string> <string name="longitude">Longitud: </string> 

<string name="defaultLongitude">-16.323004</string> <string name="result">Resultado: </string> <string name="getAddress">Obtener Dirección</string> 

Page 4: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 4/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página4de12

mostrarlos, luego sería conveniente que el usuario no pudiese modificarlo(android:enabled="false")

4.  Unavezhayamoscomprobadoqueel layout cargacorrectamente,empezaremosa

escribir código en nuestra Activity. Nuestro objetivo es utilizar los dos

primerosEditTextparaintroducirlascoordenadasGPS,elbotónpararealizarla

petición, y el últimoEditText para mostrar la salida.Por tanto,necesitamos

variablesquenospermitanreferenciarestasView;necesitaremosunareferenciaa

latitudeET,unlongitudeET,unrequestButtonyunresultET,todos

son sus tipos correspondientes (llamar las variables de la misma forma).

UtilizaremosnuestrométodoinitConfig()paracargarellayout yreferenciar

las View. A continuación, añadiremos un onClickListener al

requestButtonyharemosqueelanteriorllamealmétodomakeRequest()sinargumentos.Enestemétodoimplementaremoslapetición.

5.  Escribimosla cabecera delmétodoprivadomakeRequest()sinargumentosy

sinningúnvaloradevolver.Loprimeroquedebemoshacerenélesdesactivarlos

EditTextyelButtonparaqueelusuarionopuedarealizarmodificacionesni

llamar a este método más de una vez al mismo tiempo. Al final del método,

escribimoselcódigocontrario,esdecir,elquevuelveaactivarlosEditTextyel

requestButton.

6.  Elcódigoimportantevieneaquí.EnmediodelmétodomakeRequest()(tras

desactivarlosEditTextyelrequestButton)debemosañadirunbloque

try/catchgenérico(quecapturecualquierException)Dentrodelbloque

try/catch,introduciremoselsiguientecódigo:

Page 5: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 5/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página5de12

7.  Conestecódigoenposiciónlaaplicacióndeberíafuncionarcorrectamente.¿Ono?

¿Noshemosolvidadodealgo?Sí.QueremosrealizarunapeticiónenInternet,

luegonoshacefaltaelpermiso(uses-permission)INTERNETenelmanifest 

denuestraaplicación.

8.  Comopodemosver,laaplicaciónretornaunresultadomuylargo,dentrodelcual

seencuentralacalledelaEscuelaTécnicaSuperiordeIngenieríaInformáticade

laUniversidaddeLaLaguna ,pero,¿quéestodoestetextoquerecibimoscomo

respuesta?Yloqueesmásimportanteaún,¿porquésedetienelaaplicación

mientrasrealizalapetición?

B(2)Ejecuciónensegundoplano

 

Detengámonosunsegundoamirarloqueacabamosdehacer.Androidposeevarias

librerías incluidas, y una de ellas (HttpClient), es la que hemos utilizadopara obtener

acceso a Internet. Puede verse que primero necesitamos inicializar un objeto de tipo

HttpClienty queluego,alfinaldelapeticiónloapagamos(métodoshutdown()).En

este ejercicio hemos queridosimplificar el código lomáximoposiblepara centrarnosen lo

importante:entendercómoimplementarcomunicacionesconWebServices,peroenrealidad,

elhechodeinicializarydecerrarclientesHTTPesunaoperacióncostosa,yenaplicacionesque

requierandeaccesoaInternetalolargodemuchasActivitylorecomendadoescompartir

unúnico HttpClientcompartido,yqueéstesecierreúnicamentecuandoelusuarioyano

estéutilizandolaaplicación.

// obtenemos una conexión DefaultHttpClient httpClient = new DefaultHttpClient();String url =

"http://maps.googleapis.com/maps/api/geocode/json?latlng=" + latitude +"," + longitude + "&sensor=false";// creamos una petición de tipo GET (parámetros en la URL) HttpGet request = new HttpGet();request.setURI(new URI(url));// ejecutamos la petición HttpResponse response = httpClient.execute(request);

// convertimos la respuesta en string String responseString = EntityUtils.toString (response.getEntity());

// escribimos el resultadoresultET.setText(responseString);

// cerramos la conexiónhttpClient.getConnectionManager().shutdown();

Page 6: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 6/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página6de12

Losiguienteatenerencuentaeslarespuesta.Comoyahemosmencionado,nuestroWebServiceencuestiónposeesupropioprotocolo,unoalqueyanoshemosadaptado(en

parte) al realizar lapetición (nóteseque los parámetros estánen la URL), sin embargo, lasorpresavienealverquelarespuestanonosdalosdatosdeformadirecta,nimuchomenos.LarespuestaquetenemosesenrealidadunobjetoJSON(JavaScriptObjectNotation),alquemuchos nos gusta llamar “el sucesor del XML”. Lo común cuando se interactúa conWeb

ServicesesrecibirlarespuestaobienenformatoXML,obienenformatoJSON.XMLtienelaventaja de ser muy conocido y de que es increíblemente flexible, además de que estásoportadoporcasitodosloslenguajes.Sinembargo,tieneunagrandesventajaconrespectoalJSON,yesquerequieredelaconstruccióndeun parser ,unanalizadoroescáner,específicoparacadatipodedocumentoXML.EstosignificaqueparaunmismoWebService,podríamostener que escribir dos omás escáneres, uno por cadapetición distinta que tengamosquehacer(enlapráctica,losWebServiceintentanminimizarqueestoocurra)Esaquídondegana

elmásmoderno JSON: funciona porparejas (clave, valor), seadaptaa cualquierestructura,cadavezesmássoportado,y además,norequiereconstruirun parser específico,solamenteadaptarnosalarespuestarecibida.

Lo más importante, sin embargo, esel hechodeque nuestra aplicación sedetienecadavezquerealizalapetición.Condetenersequeremosdecirque,sinosotrosinteractuamoscon la aplicaciónmientras está realizando la llamada alWeb Service, ésta no es capaz dehacernoscaso.¿Porqué?Larespuestaesmuysimple:porqueestáocupada.

Hasta ahora, todas las acciones quehemos realizadoenAndroidhansido accionesrápidas,sinapenasretardonicomplejidad;estohapermitidoquepasemosporaltounhechomuyimportante:hemosestadoutilizandoelhilo( thread )encargadodeprocesarloseventosdelainterfazgráficaparatodasnuestrasacciones.

Es decir, la secuencia de instrucciones que mantiene viva nuestra aplicación,respondiendo cada vez que nosotros presionamos la pantalla, pulsamos un botón, osimplemente deslizamos undedopara ver cómo seiluminauna parte de la pantalla, eslamismaqueejecutatodasycadaunadelaslíneasdecódigoquehemosprogramadohastaahora(eventos,creacióndemúltiplesActivity,larotación,etc.)handetenidobrevementela capacidad de la aplicación de responder antenuestras peticiones, pero debido a que lehemospedidorelativamentepocoalhilodelainterfazgráfica,nonoshemosdadocuenta.

TodohacambiadoconlapeticiónalWebService,dondedependiendodeldispositivoy

delarednonosdamoscuenta,peroelhechoesquesiunainteracciónporpartedelusuario

tardamásdemediosegundo,elusuariomediosedacuenta,yaloscincosegundos,Android

permitealusuariocerrarlaaplicación.

Estosesolucionamoviendolaspartesdecódigolentasaotrohilo,unosecundario,quepueda realizar estas acciones en paralelo. Mientras, el hilo de la interfaz mantendrá laaplicación“viva”,ycuandoelhilosecundariotermine,podránotificaralprimerhiloparaqueactualicelainterfaz.Hagámoslo.

Page 7: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 7/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página7de12

D. Pasosaseguir1.  Debemos crear un nuevo paquete, esta vez para guardar las clases de tipo

Thread. Una vez creado, pediremos a Eclipse que añada una nueva clase,RequestThread,queheredarádelaclasejava.lang.Thread.

2.  LaclaseRequestThreadestarávacía.Losdatosquenecesitamossonlalatitud,

lalongitudyun Handler.UnHandleresunobjetodeJavacapazderecibir

mensajes(eventos)deformaasíncrona,esdecir,sindetenerelhilodeejecución

desdeelquefuellamado.Además,funcionamuybiencuandoselellamadesdeun

hilodistinto.Comenzamosañadiendoestaslíneasdecódigoalacabeceradela

claseRequestThread:

 

3.  Acontinuación,añadimosunconstructoralaclaseRequestThreadparapoder

inicializar las variables anteriores. Como siempre, lo primero que hacemos es

llamaralconstructordelpadre(constructordelaclaseThreaddeJava):

4.  Losiguienteesañadirelmétodomásimportante,elmétodorun()(público,sin

retornoyconusodel@Overrideporqueestamossustituyendounmétododelaclasepadre).Ésteeselmétododelhiloqueseejecutaensegundoplano,yaque

porlodemás,cuandovayamosacrearunobjetodetipo RequestThreaddesde

laRequestActivity,funcionarásobreelmismohilo,esdecir,sobreeldela

interfazgráfica.Copiarelsiguientecódigoalmétodorun():

 private Handler myHandler; private String latitude; private String longitude;

 public RequestThread(String latitude, String longitude,Handler myHandler) {

super();this.latitude = latitude;this.longitude = longitude;this.myHandler = myHandler;

}

Page 8: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 8/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página8de12

Revisemoselcódigoconcalma.Loprimeroesverquesetratadelmismobloque

try/catch que nos detenía la ejecución de la aplicación en el método

makeRequest() de la RequestActivity. Los cambios vienen a partir de

queobtenemoslarespuestacomoString,peroantesmiremoslanuevalínea

delbloquecatch.Enella,enviamosunmensajealHandler,unmensajevacío(sin

datos),enelqueelúnicoparámetroquehayasignaunvaloralcampo whatdel

Message.Estecampowhatseutilizaparaidentificarquéseestáenviandoconel

try {

// obtenemos una conexión DefaultHttpClient httpClient = new DefaultHttpClient();

String url ="http://maps.googleapis.com/maps/api/geocode/json?latlng=" + latitude +"," + longitude + "&sensor=false";

// creamos una petición de tipo GET (parámetros en la URL) HttpGet request = new HttpGet();request.setURI(new URI(url));// ejecutamos la petición HttpResponse response = httpClient.execute(request);

// convertimos la respuesta en string String responseString =

EntityUtils.toString (response.getEntity());

// escribimos el resultado Message msg = new Message();// de qué trata el mensaje msg.what = 0;// añadir datos Bundle data = new Bundle();data.putString(RequestActivity. __RESPONSE_KEY__,

responseString);// colocamos los datos msg.setData(data);// enviamos el mensaje myHandler.sendMessage(msg);

// cerramos la conexiónhttpClient.getConnectionManager().shutdown();

}catch (Exception e) {

e.printStackTrace();// mensaje vacío (sin datos) myHandler.sendEmptyMessage(1);

Page 9: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 9/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página9de12

mensaje;cuandosequierenenviardistintosmensajessinenviardatospesados,se

envíanmensajesvacíoscondistintosvaloresparaelcampo what.Elreceptor,que

pondremos en la clase RequestActivity, preguntará al mensaje cuál es elvalordesucampowhat,yasísabráquésignificalarecepcióndeesemensaje.Si

miramoselfinaldelbloquetry,veremosquecreamosunanuevavariabledetipo

Message, que asignamos el valor del campo what a cero (en el catch le

asignamos 1), que creamos un bundle, y que en el bundle añadimos el

Stringquehemosrecibido(comoclaveutilizamosuncampoqueañadiremos

ahoraalaclaseRequestActivity).Porúltimo,colocamoselbundleenel

mensaje,yloenviamos,sinolvidarnosdecerrarlaconexión.

5.  Como acabamos de mencionar, debemos añadir una variable pública, estática,

final(final)detipoStringconnombre __RESPONSE_KEY__alacabecera

de la clase RequestActivity. Además, debemos ir al método

makeRequest(), y eliminar todas las líneasque siguen aaquellas enlasque

desactivamoslosEditTextyelrequestButton.Acontinuación,creamosun

RequestThread a cuyo constructor le pasamos el texto de los EditText

(latitudeET,longitudeET)yunavariable(myHandler)quecrearemosen

elúltimopaso.Paraterminar,llamamosalmétodorun(),sinparámetros,del

RequestThreadqueacabamosdecrear.

6.  TraselmétodomakeRequest(),debemosañadirelsiguientecódigo:

Handler myHandler = new Handler() {

@Override  public void  handleMessage(Message msg) {

if (msg.what == 0) {// response resultET.setText((String)msg.getData().get(Request

Activity. __RESPONSE_KEY__));}if (msg.what == 1) {

resultET.setText(getString(R.string. error ));}// activamos todo latitudeET.setEnabled(true);longitudeET.setEnabled(true);requestButton.setEnabled(true);

}};

Page 10: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 10/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página10de12

Comopodéisver, el métodoesmuysencillo. Sielwhat es cero, recogemos el

StringyseloasignamosalEditTextderesultado;sies1,esqueocurrióuna

excepción,luegodebemosmostrarunmensajedeerror(dejamosesteStringalos alumnos). En cualquier caso, la ejecución del hilo termina, luego podemos

volveraactivarlosEditTextyelbotóndepetición.

E.  CuestionesyConclusionesFinales1.  ¿Porquéutilizamoselmétodostart()envezdellamaralmétodorun()

directamentedesdeelmakeRequest()enRequestActivity?Probarlo.

¿Porquésecomportadeestaforma?

2.  ¿PorquéutilizamosunHandler?¿Porquénopodemosrealizarloquehaceel

Handlerdirectamentedesdeelmétodorun()delaclaseRequestThread?

¿Quéocurresilohacemos?

3.  ¿PorquétenemostantomiedodequelallamadaalWebServicedetenganuestra

aplicación?¿Quéconsecuenciastieneestoparaelusuario?

Vayamosporpartes.Loprimeroesquesí,sonmuchosconceptosparaasimilarenun

únicoejercicio,peroésta,enrealidad,eslaformamássimpleyrealdeencontrarseconel

problema de bloquear (o detener) el hilo de la interfaz gráfica. Este problema lo vivimos

constantemente con las aplicaciones de escritorio que utilizamos, sin embargo, en un

smartphonelasituaciónresultasermuchomásestresante,yaqueelusuarionotieneningún

sitioalquecorrersinuestraaplicaciónsaturaalsistemaoperativo(dependiendodelteléfono,

esposiblevolverlotanlentoqueelpropioprocesoHOMEtengaquecerrarse),alcontrarioque

enWindowsy enMac,dondepodemoscerrarlasaplicacionesyvolveraabrirlassinoshace

falta.Esta estrategia deThread(s) yHandler(s)noesexclusivadeAndroid,ypuede

utilizarseperfectamenteen Java.Sinembargo,cabemencionarquenoes laúnicaformade

realizar esta gestiónen Android; haydos tiposmásqueesperamos verenun futurocurso

AvanzadodeAndroid.

LosiguienteesreforzarlaimportanciadelosMessage.Cuandoseenvíaunmensajea

unHandler

, éste es colocado al final de una cola para ser procesado por el método

handleMessage()quenosotrossustituimosennuestroHandler.Estoocurredeforma

asíncrona, provocando que el hilo en el que se encuentra el handler ejecute un

handleMessage() con el mensaje correspondiente. Esto nos permite utilizar esta

estrategia con mucha flexibilidad; podemos crear tantos eventos (valores del argumentowhat) como queramos, permitiéndonos conocer en cualquiermomento en qué estado se

encuentranuestrohiloen segundoplano.Naturalmente,lautilidaddeestaestrategia sevemejorcuantomáscomplicadaes lainteracciónentreelhiloensegundoplanoyelhilodelainterfazgráfica.Podríainclusoutilizarseunúnicohandlerpararecibireventosdemúltiples

hilos, pues todos van a la misma cola.Ahora bien, las accionesque llevemos a caboenel

Page 11: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 11/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página11de12

handlernopuedenserlentas(esdecir,nopuedendetenerelhilodelainterfazgráfica),oestaremosdevueltaenelmismopuntodelquepartimos.

Ahora vienen los hilos. El hilo de tipo RequestThread que creamos desde la

RequestActivity,enrealidad,seejecutadesdeelmismohiloquelocreó(esdecir,elde

lainterfazgráfica)Sinosotrosllamásemosalmétodo run()directamente,seríacomosiel

hilonoexistiese,porqueseríacomosiejecutásemosunmétodomásdeunobjetocualquiera;esdecir, seejecutaríadesdeelhilode lainterfaz,luegoelesfuerzoquehemoshechohabrásidoenvano.

En realidad, las clases Thread y similares (Runnable) lo que hacen es

proporcionarnosunaformafácilde ejecutar códigoen otrohilo sinquenosotros tengamosquerealizarningunagestión.Poresolautilidaddelaclase Threadradicaenqueutilicemosel

método start(), porque se encarga de crear un nuevo hilo y de mantenerlo enfuncionamientoejecutandocódigo,yelcódigoqueejecutaes,porsupuesto,el delmétodorun().

Nota:LaclaseThreadproporcionamásmétodosparacontrolarlaejecucióndelhilo

queejecutaelmétodorun().Sehanobviadoparasimplificareltextoytransmitirlasideas

principales.Sinembargo,ejecutarcódigoensegundoplanoesunpocomáscomplicadodeloque

hemos dicho hasta ahora. Si nosotros intentáramos llamar a las Views desde el método

run() del hilo, obtendríamos una excepción en tiempo de ejecución, una excepción

medianamente grave. Esto se debe a que las Views no pertenecen al hilo que estáejecutando el código (RequestThread), sino a otro (hilo de interfaz de

RequestActivity)Esunaconvenciónen frameworksdeprogramaciónconinterfazgráfica(.NET, Cocoa, Cocoa Touch, y por supuesto Android) que los elementos de la interfaz sólopuedan ser llamados desde el propio hilo que los creó. Esto da lugar a un concepto muyutilizado,elde thread safety .Cuandounelementoes thread safe, significaquepuede serutilizado(llamado)desdecualquierhilo.EnelcasodeAndroidloselementosdelainterfaz(Views) no son thread safe. Es aquí donde el handler comienza a tener sentido; los

métodosquepermitenenviarlemensajesalhandlersonthreadsafe,ycomoyadijimos,el

métodoqueprocesalosmensajesseejecutadesdeelhiloquecreóel handler(ennuestro

caso, elde la interfaz deRequestActivity) Así decómo hemosdecidido solucionar el

problemadecomunicarnosdesdeelcódigoejecutandoen segundoplano conla interfazenesteejercicio,perocomoyahemosdicho,haymássoluciones.

Existen otros métodos para realizar comunicaciones con un servidor; Android, al

implementar un subconjuntode Java 5, suele sermuy flexible importando librerías hechasparaJava(archivos .jar),loquenospermiteutilizarotralibreríaconlaquenossintamos

máscómodosoinclusoaportaralgoquenopermitíalalibreríaqueincluyeAndroid,comoporejemplo, el envío de archivosmediante unPOST (recomendamos utilizar la libreríaApache

Commons para esto) Sin embargo, llegados a cierto punto, simplemente conocer cómo

Page 12: Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano

5/14/2018 Ejercicio Avanzado B - Web Services y Ejecución en Segundo plano - slidepdf.com

http://slidepdf.com/reader/full/ejercicio-avanzado-b-web-services-y-ejecucion-en-segundo-plano 12/12

 

Desarrollo de Aplicaciones Móviles en AndroidEjercicio Avanzado A: Bases de Datos y conexión con un ListView utilizando vistas personalizadas Autores: Jorge Carballo Franquis

David D. Harjani Harjani 

Página12de12

funcionalaplataformaolibreríaconlaqueestemostrabajandononosllevarámáslejos,sinoqueseránuestroingenioelquetendráqueresolverlosproblemasquenohansidoresueltos.