# Ejercicios

## Cargar y trocear XML

En este ejercicio vamos a hacer un sencillo lector de RSS. Crea una nueva aplicación llamada ParseXML con un interfaz similar al de la siguiente imagen:

![](https://888516061-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LwrBJxp0xTANGM036-G%2F-LwrBLLK_CMs3zo9_Yuv%2F-LwrBUsnWj5HqvAoku5-%2Fs15_1_rss.png?generation=1577179050143127\&alt=media)

Como se puede ver la interfaz está compuesta de un `EditText` donde se introducirá la URL, un botón y un `TextView` que ocupará el resto del espacio. Cuando se pulse el botón se tendrá que descargar el XML desde la URL indicada, trocearlo, y mostrar los resultados en el `TextView`.

* Añade al `AndroidManifest.xml` los permisos para utilizar Internet.
* Crea un método `accionDescargar()` que se encargará de recoger la URL del `EditText` y de introducir los resultados en el `TextView`.
* Necesitarás buscar tags `item`, y dentro de cada uno de ellos habrá tags `title` y `link` cuyo texto tendrás que añadir al resultado. Si no buscas las aperturas y cierres de `item`, también se mostraría el título de la propia página, que en realidad no es ninguna noticia que queramos mostrar.
* Opcional: Muestra también la fecha de cada noticia.

> Nota: en este ejercicio todavía no es necesario que metas la descarga de contenidos en una AsyncTask.

## Operaciones largas de caraga de datos

Si la página web tardara en cargarse, el programa del ejercicio anterior se quedaría congelado durante el tiempo de la descarga. Si este fuera superior a 2 segundos, podríamos obtener un mensaje de que la aplicación no responde y si deseamos cerrarla. Este tipo de experiencia de usuario es totalmente indeseable.

El emulador nos permite simular conexiones lentas de la siguiente manera. Desde línea de comandos:

```bash
telnet localhost 5554
network delay gprs
OK
network speed gsm 
OK
```

Esta acción también podemos hacerla desde el DDMS (Android Device Monitor) que incorpora el SDK.

Vamos a intentar cargar el RSS de un sitio lento, o bien formar la descarga lenta usando los comandos anteriores el DDMS.

La solución a las operaciones largas es la creacion de hilos o `Thread`. El problema de los hilos es que los componentes gráficos sólo deben ser modificados desde su propio hilo, y no desde otro. Por tanto hay que separar el código de la tarea que va en el segundo hilo, y de la modificación de los componentes, que debe ejecutarse en el hilo principal.

A partir de Android 1.5 se introdujo una nueva clase que nos facilita la programación de tareas en segundo plano: `AsyncTask`.

* Vamos a modificar el código del ejercicio anterior, introduciendo la carga y parseo de XML en el método `doInBackground(...)` de una nueva clase que extienda a `AsyncTask`.
* Tendremos que separar la actualización de componentes y pasarla a los métodos `onPostExecute(...)` y `onProgressUpdate(...)`. Una forma sería ir cargando el resultado en un campo String que declaramos en la clase, para finalmente actualizar el resultado en el campo de texto. También se puede ir actualizando conforme se va cargando.
* Añadir un campo de texto en la parte superior de la pantalla. En él se indicará el progreso de la descarga, por tanto será actualizado por el método `onProgressUpdate(...)`. Este método deberá ser llamado varias veces a lo largo del progreso de la carga, y lo tenemos que hacer explícitamente desde el método `doInBackground(...)`, con una llamada a `publishProgress("Cargando item número "+n)`.
* Finalmente para iniciar la tarea hay que crear un objeto de la nueva clase que hemos creado, y ejecutar su método `execute(...)`, pasándole como parámetro la dirección de la RSS. Si hemos hecho los anteriores puntos, veremos el progreso de la carga en el nuevo campo de texto que hemos añadido.

## Lector de RSS - versión gráfica

En este ejercicio vamos a ampliar el código del anterior organizando las noticias en una lista de objetos de tipo `Noticia`. Después vamos a crear un adaptador para que las noticias puedan ser cargadas en un `ListView`. Aprovecharemos para añadir una imagen si la hay.

El aspecto final que deberá tener nuestro Lector de RSS será el siguiente:

![](https://888516061-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LwrBJxp0xTANGM036-G%2F-LwrBLLK_CMs3zo9_Yuv%2F-LwrBUspN5RzzXqwPLHB%2Fs15_3_rss.png?generation=1577179050031028\&alt=media)

* Crea una clase `Noticia` con los siguientes campos:

```java
private String titulo;
private String descripcion;
private String link;
private String fecha;
private String linkImagen;
private Drawable imagen;
```

Genera getters y setters para todos ellos, y un constructor que los inicialice a "" y a null la imagen. Añade también un método `public void loadImagen(String url)`. Escribe en él el código que carga en el campo `imagen` un `BitmapDrawable` cargado desde la URL indicada (Se puede utilizar un `InptuStream` que se obtenga a partir de un objeto de tipo `URL`, ver la sección correspondiente de la teoría).

* Copia en el método `doInBackground(...)` el código que parsea el XML

  y rellena la noticia con los campos de Título, Fecha, Descripción, Link, LinkImagen.

  Hay que tener en cuenta que puede haber diferentes formatos de RSS. Para simplificar el

  problema vamos a intentar que funcione al menos para los dos siguientes ejemplos:
* <http://barrapunto.com/index.rss>

  ```markup
  <item rdf:about="http://softlibre.barrapunto.com/article.pl?sid=10/08/13/0728242&from=rss">
    <title>Oracle demanda a Google por Android</title>
    <link>http://softlibre.barrapunto.com/article.pl?sid=10/08/13/0728242&from=rss</link>
    <description>Oracle ha presentado una demanda contra Google asegurando que ..."</description>
    <dc:creator>mig21</dc:creator>
    <dc:date>2010-08-13T07:30:00+00:00</dc:date>
    <dc:subject>Oracle</dc:subject>
    <slash:department>patent-IP-trolling</slash:department>
    <slash:section>softlibre</slash:section>
    <slash:comments>85</slash:comments>
    <slash:hit_parade>85,83,41,29,11,7,3</slash:hit_parade>
  </item>
  ```
* <http://www.meneame.net/rss2.php>

  ```markup
  <item>
    <meneame:link_id>1025318</meneame:link_id>
    <meneame:user>Whitefox</meneame:user>
    <meneame:votes>147</meneame:votes>
    <meneame:negatives>0</meneame:negatives>
    <meneame:karma>616</meneame:karma>
    <meneame:comments>25</meneame:comments>
    <meneame:url>http://techcrunch.com/2010/08/13/android-oracle-java-lawsuit/</meneame:url>
    <title>Google responde a la denuncia sobre Android presentada por Oracle</title>
    <link>http://m.menea.me/lz52</link>
    <comments>http://m.menea.me/lz52</comments>
    <pubDate>Sat, 14 Aug 2010 09:40:02 +0000</pubDate>
    <dc:creator>Whitefox</dc:creator>
    <guid>http://m.menea.me/lz52</guid>
    <description>... ]></description>
    <media:thumbnail 
      url="http://aws.mnmstatic.net/cache/a5/26/thumb-1025318.jpg" 
      width='75' height='49' />
    <wfw:commentRss>http://www.meneame.net/comments_rss2.php?id=1025318
    </wfw:commentRss>    
  </item>
  ```

Recuerda que cada vez que se cierre un `item` en el XML, habrá que añadir el nuevo objeto `noticia` al ArrayList `noticias`.

* Asignar un `OnItemClickListener` al `ListView` para que al hacer

  click sobre una noticia, se muestre un `Toast` con la información de la noticia.

  Opcionalmente se puede lanzar un navegador del sistema que nos lleve a la URL de la noticia.
