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.
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/
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>
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:
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();
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.
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;
}
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);
}
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);
}};
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
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
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.