Acceder

Ver la Versión Completa : [ CONSULTA ] Duda con AsyncTask


Bongiovi
13/07/13, 12:40:06
Estoy empezando a programar en android y me encuentro realizando una app donde incluyo lo que voy aprendiendo.

El tema es que la app tiene dos activities, la segunda se lanza cuando se pulsa un boton de la primera. El LinearLayout de la segunda se compone de dos TextViews. El primero debe aparecer inmediatamente, al crearse la Activity, pero el segundo requiere un minuto porque el telefono realiza unos calculos y hasta que no pasan 60 segundos no muestra el TextView correspondiente.

El problema es que no se muestra el primer TextView desde el principio, si no que se queda la pantalla en negro durante 60 segundos y luego muestra ambos TextViews a la vez.

He probado de todo tanto en xml como directamente en Java. ¿Como soluciono esto?

Como véis, es una duda de principiante total, ya digo que estoy empezando ;)


Gracias y un saludo.

EDITO:

Otra dudita en la respuesta #7 ;-)

Reutilizo el post para no crear otro nuevo.

Estoy teniendo problemas utilizando la clase AsyncTask.
La app consiste en dos sencillas Activities, la primera lanza el Intent a la segunda sin problemas.
La segunda Activity tiene 2 TextViews, al principio solo se muestra uno, mientras que el segundo permanece oculto. Hasta aquí todo OK.
El segundo TextView debería mostrarse al concluir la AsyncTask, pero la aplicación da FC cuando esto pasa :(.

Aquí los códigos:

- Layout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/MainLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/CalculoMensaje"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/calculo_mensaje"
android:layout_weight="1"/>

<TextView
android:id="@+id/ResultadosMensaje"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:layout_weight="4"
android:visibility="invisible"/>

</LinearLayout>

- Java.

public class Calculo extends Activity
{
TextView view;

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
view = (TextView) findViewById(R.id.ResultadosMensaje);
setContentView(R.layout.calculo_activity);

calculoAsincrono task = new calculoAsincrono();
task.execute();
}
public class calculoAsincrono extends AsyncTask<Void, Void, Double>
{
@Override
protected Double doInBackground(Void... params)
{
// Cálculos realizados durante 60 segundos.
return index;
}

@Override
protected void onPostExecute(Double index)
{
StringBuilder builder = new StringBuilder();
builder.append("Tu CPU ha realizado " + index + " operaciones en un minuto.");
view.setText(builder.toString());
view.setVisibility(TextView.VISIBLE);
}
}
}


Prefiero investigar y aprender por mí mismo antes que que me expliquen los errores, pero esto me trae de cabeza X-D
Alguna solución?

Saludos!


Solucionado, solo había que cambiar la línea "TextView view;" dentro del método "onCreate".

kriogeN
13/07/13, 12:45:11
El problema está en que los cálculos seguro que los estás haciendo en el hilo principal, y lo que es más, en el onCreate de la Activity. ¿Me equivoco?

Para solucionar tu problema tienes que hacer lo siguiente:

1) Establecer al segundo TextView como INVISIBLE (o GONE, esto ya a gusto del efecto que quieras)
2) En el onCreate lanzar un AsyncTask, que durante su doInBackground realice los cálculos.
3) Finalmente en el onPostExecute del AsyncTask estableces el setText del TextView y lo haces VISIBLE.

Bongiovi
13/07/13, 12:56:11
El problema está en que los cálculos seguro que los estás haciendo en el hilo principal, y lo que es más, en el onCreate de la Activity. ¿Me equivoco?

Para solucionar tu problema tienes que hacer lo siguiente:

1) Establecer al segundo TextView como INVISIBLE (o GONE, esto ya a gusto del efecto que quieras)
2) En el onCreate lanzar un AsyncTask, que durante su doInBackground realice los cálculos.
3) Finalmente en el onPostExecute del AsyncTask estableces el setText del TextView y lo haces VISIBLE.

Como bien dices, hago los cálculos en el onCreate xD

Esto de AsyncTask me suena a chino, ahora me informaré en android developers.

Muchas gracias, saludos!

rafaxplayer
13/07/13, 13:41:32
Exactamente necesitas hacer los calculos en otro hilo para que que el principal no se demore y muestre la interfaz , asynctask es una de las mejores opciones.

mocelet
13/07/13, 14:26:55
Dado que la tarea es de muy larga duración, para hacerlo bien del todo deberías detener los cálculos cuando la actividad pase al estado de onPause u onStop.

Si no, cuando el usuario cambie de aplicación porque le llaman o recibe un mensaje estará la tarea de fondo robando CPU y enlenteciendo el sistema entero sin necesidad porque la actividad ni si quiera se está mostrando ya.

Lo comento porque las AsyncTask no se detienen solas cuando la actividad se detiene.

P.D: La nueva forma "elegante" de inicializar/cargar/calcular datos al iniciar una actividad son los Loader, si bien en tu caso es matar moscas a cañonazos.

Bongiovi
13/07/13, 14:34:54
Dado que la tarea es de muy larga duración, para hacerlo bien del todo deberías detener los cálculos cuando la actividad pase al estado de onPause u onStop.

Si no, cuando el usuario cambie de aplicación porque le llaman o recibe un mensaje estará la tarea de fondo robando CPU y enlenteciendo el sistema entero sin necesidad porque la actividad ni si quiera se está mostrando ya.

Lo comento porque las AsyncTask no se detienen solas cuando la actividad se detiene.

P.D: La nueva forma "elegante" de inicializar/cargar/calcular datos al iniciar una actividad son los Loader, si bien en tu caso es matar moscas a cañonazos.

Estos detalles los tengo apuntados para implementar (creo que no se me pasa casi nada debido a lo sencillo de la app), pero me faltan conocimientos y experiencia aún X-D

Ahora mismo estoy leyendo sobre las tareas en segundo plano en sgoliver.

Gracias y un saludo.

Bongiovi
13/07/13, 19:11:42
Otro problema, esta vez relacionado con la clase Bundle.

Tengo dos activities, en el Intent que va de una a otra incluyo un objeto de la clase Bundle, el cual incluye un string. Pues bien, una vez estoy en la segunda activity, el método getString("nombreDeLaVariable") de la clase Bundle me devuelve "null".

He puesto un breakpoint y el Bundle contiene el String, ¿que pasa aquí?

kriogeN
13/07/13, 19:19:17
No se como estarás pasando el parámetro en la primera Activity, pero prueba con esto en la segunda:

getIntent().getStringExtra("nombredelavariable")

Si te sigue dando NULL, para poner el parámetro en la primera Activity usa esto, y suponiendo que el Intent que declaras se llame "intent":

intent.putExtra("nombredelavariable",objeto_tipo_string)

Bongiovi
13/07/13, 19:42:03
No se como estarás pasando el parámetro en la primera Activity, pero prueba con esto en la segunda:

getIntent().getStringExtra("nombredelavariable")

Si te sigue dando NULL, para poner el parámetro en la primera Activity usa esto, y suponiendo que el Intent que declaras se llame "intent":

intent.putExtra("nombredelavariable",objeto_tipo_string)

Arreglado, con la primera modificación que me has dicho seguía pasando lo mismo, per con la segunda todo bien :ok:

Supongo que el problema es que el Bundle no reconocía el string como tal, no?