Programación y Desarrollo para Android Subforo exclusivo para temas de programación de software para PDAs y desarrollo de aplicaciones, interfaces, etc bajo Android

Respuesta
 
Herramientas
  #1  
Viejo 25/03/15, 11:06:35
Array

[xs_avatar]
oxot oxot no está en línea
Usuario muy activo
 
Fecha de registro: may 2010
Localización: Santiago
Mensajes: 741
Modelo de smartphone: Xiaomi RedRice
Tu operador: Pepephone
Clases internas anónimas y variables externas

Buenos días,
estoy programando un app que hace una serie de consultas REST para lo que he decido usar la librería loopj (loopj.com/android-async-http/) para que se encargue de manejar todas las tareas asíncronas.

Entonces, tengo una activity contenera, un fragment que tiene una lista y otra clase que me guarda todas las consultas REST.

Mi problema es el siguiente:
Cuando realizas cualquier consulta, por ejemplo un get, lo haces por ejemplo con:

Código:
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
    @override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        // called when response HTTP status is "200 OK"
    }

    @override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
        // called when response HTTP status is "4XX" (eg. 401, 403, 404)
    }
});
y como véis se utilizan clases internas anónimas como manejadores. El problema es que en onSuccess yo quiero actualizar una lista externa (que tengo en la clase fragment) pero Java protesta porque desde clases internas anónimas sólo puede manejar variables de método 'final' o variables de clase (que serían de la clase dónde están las consultas REST).

El problema es que no puedes hacer un método en plan
Código:
public Lista miMetodo(){
hazLaConsultaGet();
return laLista;
}
porque la consulta es asíncrona y entiendo que el método no espera a que retorne la consulta sino que devolverá una lista inválida.

Tampoco puedo hacer un return en onSuccess porque tengo que sobreescribir el método de clase y es de tipo void (menudo tela porque en asynctask esto te soluciona el problema).

Yo sólo veo dos soluciones pero me gustaría que gente que sabe de Java más que yo me contase si hay algún procedimiento estándar para estas situaciones:
1.- Usar listeners que implemento en la clase en la que tengo la lista.
2.- Hacer el handler no anónimo instanciándolo antes de la consulta (aunque no estoy seguro que esto resolviese el problema)

A ver si alguien se anima a darme ideas.



PS. Espero haber explicado claramente cómo va el tema. Es un poco lioso pero lo he tratado de simplificarlo.
Responder Con Cita


  #2  
Viejo 25/03/15, 12:01:31
Array

[xs_avatar]
mocelet mocelet no está en línea
Desarrollador
 
Fecha de registro: may 2011
Localización: Madrid
Mensajes: 2,202
Tu operador: -

Lo único que necesitas es una referencia al objeto que quieras llamar, pero de tipo final, claro.

Es decir, antes del client.get(...) pones un:

final ClaseQueSea objeto = instanciaQueQuierasUsar

Y dentro de onSuccess o onFailure puedes llamar a cualquier método de ese objeto que no te dará la brasa con lo de que no es final.

Como bien dices, la gracia del asíncrono es que no bloquea el hilo de ejecución, simplemente se ejecuta algo en segundo plano y cuando termina avisa. Los callbacks o listeners de esa biblioteca los hace en el hilo principal, así que una preocupación menos.
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!

Última edición por mocelet Día 25/03/15 a las 15:13:39.
Responder Con Cita
Gracias de parte de:
  #3  
Viejo 25/03/15, 12:47:29
Array

[xs_avatar]
oxot oxot no está en línea
Usuario muy activo
 
Fecha de registro: may 2010
Localización: Santiago
Mensajes: 741
Modelo de smartphone: Xiaomi RedRice
Tu operador: Pepephone
 Cita: Originalmente Escrito por mocelet Ver Mensaje
Lo único que necesitas es una referencia al objeto que quieras llamar, pero de tipo final, claro.

Es decir, antes del client.get(...) pones un:

final ObjetoQueSea objeto = instanciaQueQuierasUsar

Y dentro de onSuccess o onFailure puedes llamar a cualquier método de ese objeto que no te dará la brasa con lo de que no es final.

Como bien dices, la gracia del asíncrono es que no bloquea el hilo de ejecución, simplemente se ejecuta algo en segundo plano y cuando termina avisa. Los callbacks o listeners de esa biblioteca los hace en el hilo principal, así que una preocupación menos.
Entiendo, al pasar la referencia del objeto lo que es final será la referencia pero no el objeto en sí, del que podré modificar su contenido.
Esto es lo que me propones verdad?

Me costaría adaptarlo a mi app porque estoy trabajando con arrays de objetos (cada objeto un elemento de la lista, supongo que tendría que borrar su contenido y volver a rellenarla) pero sin embargo me la apunto porque es algo en lo que no había pensado.

Le estoy dando una oportunidad a los listeners, con los que hasta ahora no había trabajado

Última edición por oxot Día 25/03/15 a las 12:50:05.
Responder Con Cita
  #4  
Viejo 25/03/15, 13:04:41
Array

[xs_avatar]
kriogeN kriogeN no está en línea
Colaborador/a
· Votos compra/venta: (1)
 
Fecha de registro: oct 2010
Localización: Murcia
Mensajes: 4,637
Modelo de smartphone: Samsung Galaxy S7 Edge SM-G935F
Tu operador: Vodafone
 Cita: Originalmente Escrito por oxot Ver Mensaje
Entiendo, al pasar la referencia del objeto lo que es final será la referencia pero no el objeto en sí, del que podré modificar su contenido.
Esto es lo que me propones verdad?

Me costaría adaptarlo a mi app porque estoy trabajando con arrays de objetos (cada objeto un elemento de la lista, supongo que tendría que borrar su contenido y volver a rellenarla) pero sin embargo me la apunto porque es algo en lo que no había pensado.

Le estoy dando una oportunidad a los listeners, con los que hasta ahora no había trabajado
Es la misma referencia que el objeto que no es final, pero de esa forma "engañas" (realmente no es engañarlo, pero para que me entiendas) a Java para que lo acepte. Yo también uso ese truco para eventos en Adapters basados en la posición.

Lo único que hace un final es que no puedes cambiar la referencia, pero el objeto será el mismo.

Es decir, si tienes un objeto de tipo ArrayList es lo mismo hacer:

ArrayList a = new ArrayList();
a.add(e);

Que hacer:

ArrayList a = new ArrayList();
final ArrayList b = a;
b.add(e);

En ambos casos al final "a" contendrá al elemento "e"

Lo que no puedes hacer es esto:

final ArrayList b = new ArrayList();
b = new ArrayList();

En ese caso Java se quejará porque b es final, y por tanto no puedes cambiar su referencia.
Responder Con Cita
Gracias de parte de:
Respuesta

Estás aquí
Regresar   Portal | Indice > Todo sobre Android > Programación y Desarrollo para Android



Hora actual: 09:32:39 (GMT +2)



User Alert System provided by Advanced User Tagging (Lite) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.

Contactar por correo / Contact by mail / 邮件联系 /