Contenido sobre Android
Buscar
Social
Ofertas laborales ES

Foro sobre Android > Duda básica en Asynctask

Hola a todos,

Llevo bastante tiempo con una duda que no me deja avanzar en mi proyecto. Soy muy novato y creo que la solución es más sencilla de lo que creo, duda conceptual más que otra cosa:

Tengo una asynctask que realiza un get de una URL mediante código PHP. En el método onPostExecute actualizo una variable String con el contenido de la respuesta del servidor. Antes de nada decir que la tarea asynctask funciona correctamente.

El problema está al acceder al contenido de la variable desde el hilo principal. Es decir, una vez ejecutada la tarea --> new Tarea1().execute(); en la siguiente línea el contenido de la variable es null. ¿Por qué? La clase es pública.

Si os fijáis en el código, el Toast que tengo en onPostExecute muestra el dato del servidor de forma correcta, sin embargo el último Toast (una vez ejecutada la tarea) ya devuelve null. Necesito pasar ese contenido al hilo principal.

Alguna observación más: Una vez ejecutada la tarea, si instancio un objeto y llamo al método getStatus, éste me devuelve "PENDING". Es decir, todavía no ha ejecutado la tarea en segundo plano.

Os paso el código:

public class juego extends Activity {

String salida;
public class Tarea1 extends AsyncTask<TextView, Void, String> {

String dato() {
String url = "http://miservidor/obtenerdato.php";
HttpClient cliente = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);

try {
HttpResponse resp = cliente.execute(httpget);
HttpEntity ent = resp.getEntity();
String text = EntityUtils.toString(ent);
return text;
}
catch(Exception e) {
return e.toString();
}
}

@Override
public String doInBackground(TextView... params) {
return dato();
}

@Override
public void onPostExecute(String result) {

salida = result;
Toast.makeText(getBaseContext(), "dentro de asynctask: " + salida, Toast.LENGTH_LONG).show();

}
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.juego);

new Tarea1().execute();

Toast.makeText(getBaseContext(), "salida: " + salida, Toast.LENGTH_LONG).show();

}
}

Como véis, el código es muy sencillo, y debo de estar pasando por alto algo trivial.

Os doy las gracias por adelantado.

septiembre 12, 2014 | Unregistered Commenterseudo

Creo que tu error es de concepto, como el propio nombre indica es una AsyncTask por lo tanto es asíncrona, es decir que devolverá sus resultados cuando los tenga y no se ejecutará linealmente en tu código.

Esto quiere decir que tu Toast de salida se está ejecutando antes de que termine la tarea asincrona.

Pasarlo al hilo principal ya lo has pasado en el postExecute lo has guardado correctamente en la variable salida. Ahora sólo tienes que usarla al pinchar un botón o lo que sea.

Saludo.

septiembre 16, 2014 | Registered Commenterantuansoft

Entiendo, pero la ejecución de la asynctask se realiza en menos de 1 segundo. Si después de la ejecución de la asynctask le pongo un sleep de 10 segundos por ejemplo (tiempo más que suficiente para ejecutar el script PHP y actualizar la variable "salida"), ésta continúa null. Es como si no la pasara al hilo principal.

Necesito utilizar la variable después de la ejecución de la tarea y sin embargo nicamente puedo usarla dentro de onPostExecute.

Muchas gracias.

septiembre 16, 2014 | Unregistered Commenterseudo

Quizás es un poco chapuza, pero sólo veo tres soluciones:
1- Lo ejecutas en el onPostExecute tal y como lo tienes.
2- Llamas a un método de la clase juego desde onPostExecute.
3- Te creas una interfaz que implementas en la clase juego y que sirve para comunicar
entre la asinctask y la clase.

septiembre 17, 2014 | Registered Commenterjmtu

Olvidate de los Sleep no sé si eso para absolutamente toda la ejecución tendría que probarlo pero espero que no pensaras dejar ese sleep hay para siempre porque entonces no tiene sentido hacerlo asincrono.

Lo que quieres lo tienes que hacer dentro del onPostExecute realizas todo lo que necesites. Puedes crearte un método en la clase juego que haga lo que necesitas.


public class juego extends Activity {
String salida;

private void hacerAlgoConSalida(){

//Aqui puedo acceder a la variable salida que ya estará cargada.

}


public class Tarea1 extends AsyncTask<TextView, Void, String> {

.....
.....

@Override
public String doInBackground(TextView... params) {
return dato();
}

@Override
public void onPostExecute(String result) {

salida = result;
hacerAlgoConSalida();

}

}

septiembre 17, 2014 | Registered Commenterantuansoft

El sleep no pensaba dejarlo ahí. Era simplemente para verificar que la variable la pasaba al hilo principal una vez terminada la ejecución de la tarea, pero parece ser que no es así. Creo que, efectivamente, el sleep para toda la ejecución y tampoco vale para probar.

Crearé un método como dices. A ver qué tal...

Muchas gracias.

septiembre 18, 2014 | Unregistered Commenterseudo