Mostrando entradas con la etiqueta Exception. Mostrar todas las entradas
Mostrando entradas con la etiqueta Exception. Mostrar todas las entradas

sábado, 1 de junio de 2013

Android Tip: NullPointerException en android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:355)

Este error me ha traído de cabeza más de una vez, y tanto su causa como su solución son muy simples. Seguramente tengas en tu aplicación un ListView con un ArrayAdapter, y le estés añadiendo un valor nulo.

En mi caso suelo usar esta solución para mostrar valores sacados de la base de datos como, por ejemplo, una lista de jugadores. Si hay algún registro con el valor vacío, se recuperará como null, y al agregarlo al ArrayAdapter provocará la excepción.

Basta con controlar los valores nulos con algo tan simple como esto:

if (player != null) {
     playersArrayAdapter.add(player);
}

jueves, 9 de mayo de 2013

CalledFromWrongThreadException


Uno de los requisitos clásicos de Android es que cualquier modificación sobre una vista debe ser realizada desde el hilo que la creó (generalmente referido como el UI Thread). Esto hace que no sea raro que cuando empecemos a trabajar con hilos acabemos encontrándonos con la excepción:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Ante esta excepción lo primero que tenemos que preguntarnos es si realmente queremos modificar la vista desde donde lo estamos haciendo. Si la respuesta es afirmativa, podemos recurrir al método runOnUiThread de la clase Activity. Un posible ejemplo de uso sería el siguiente.

Tenemos una actividad de una aplicación que permite conexiones por bluetooth. En pantalla se muestra un botón, y cuando lo pulsamos, ponemos en marcha un servidor, que se mantiene a la espera de conexiones. Este trabajo se realiza en un hilo independiente que es lanzado desde nuestra actividad. Lo que queremos conseguir es mostrar un texto informando de que el servidor está esperando conexiones, y ocultarlo cuando éste se detenga.

Damos a nuestro hilo una referencia a la actividad, y en ésta añadimos un método para mostrar u ocultar el texto informativo. Al final del método run() del hilo añadimos una llamada a ese nuevo método.

public class XXX extends Thread {
....

public void run() {
...
activity.setTextVisible(false);
}
...
}

public class XXX extends Activity {
...
public void setTextVisible(boolean visible) {
text.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}

Excepción asegurada.

Pero si cambiamos la implementación del método setTextVisible a:

public void setTextVisible(boolean visible) {
runOnUiThread(new Runnable() {
public void run(){
text.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}
});
}

Todo marchará como la seda.

domingo, 30 de octubre de 2011

Error de Jasper Server

Este error me lo encontré hace unos días ejecutando informes en Jasper Server.


 ERROR JSErrorPage_jsp,http-8080-Processor24:329 - 
java.lang.NullPointerException
at com.jaspersoft.jasperserver.war.action.ViewReportAction.checkForParams(ViewReportAction.java:143)
at sun.reflect.GeneratedMethodAccessor337.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
...

Un puntero nulo en un método que, si nos fiamos de su nombre, comprueba los parámetros del informe.

Aunque en principio supuse que el problema debería ser que el valor de alguno de los parámetros fuese nulo, lo que realmente ocurre cuando nos encontramos este error es que hemos definido un Input Control asociado al reporte en el servidor, y éste no encuentra correspondencia en el jrxml. Hay que tener en cuenta que la relación se establece entre el id del Input Control y el nombre del parámetro.

lunes, 6 de junio de 2011

InstantiationException

En cuanto uno empieza a hacer cositas con reflexión en Java, es normal que se encuentre tarde o temprano con la excepción InstantiationException. Hasta la versión 1.5, el api de Java indicaba respecto a esta excepción algo así como:

Lanzada cuando una aplicación intenta crear una instancia de una clase utilizando el método newInstance de la clase Class, pero el objeto no puede ser instanciado porque es una interfaz o una clase abstracta.

Este mensaje tenía la habilidad de hacernos pensar que los especificados eran los únicos motivos que podían hacer que se lanzase esta excepción. Pero entonces, si estamos absolutamente seguros de que estamos intentando instanciar una clase no abstracta, ¿por qué me puede aparecer el error?

Pues por ejemplo, porque estés ejecutando algo así:

Object o = Class.forName("Clase").newInstance();

Y en la clase Clase no tengas explícitamente definido el constructor sin parámetros. Simplemente añadiéndolo a la definición de la clase solucionaremos entonces el problema.

Es por esto que a partir de la versión 6, el api de la clase InstantiationException ha cambiado su descripción a:

Lanzada cuando una aplicación intenta crear una instancia de una clase utilizando el método newInstance de la clase Class, pero el objeto no puede ser instanciado. La creación de la instancia puede fallar por varios motivos, incluyendo, pero no limitándolos a:

  • El objeto representa a una clase abstracta, una interfaz, un array, un tipo primitivo o void.
  • La clase no tiene constructor sin argumentos.
Mucho mejor.