Foros del Web » Programando para Internet » Android »

[SOLUCIONADO] Problema con AsyncTask, processFinish y el hilo principal.

Estas en el tema de Problema con AsyncTask, processFinish y el hilo principal. en el foro de Android en Foros del Web. A ver si alguien puede ayudarme, me explico: Tengo una actividad con dos fragment, en uno van los datos generales que obtengo de una base ...
  #1 (permalink)  
Antiguo 20/05/2016, 11:32
 
Fecha de Ingreso: mayo-2014
Mensajes: 45
Antigüedad: 10 años, 6 meses
Puntos: 0
Problema con AsyncTask, processFinish y el hilo principal.

A ver si alguien puede ayudarme, me explico: Tengo una actividad con dos fragment, en uno van los datos generales que obtengo de una base de datos y en el otro el mapa de situación.
Los datos los obtengo de una base de datos con una clase que extiende de AsyncTask en onPostExecute(String nombre). Una vez que he obtenido los datos (en este caso el nombre), este lo tengo que pasar a la actividad principal a:
public String getMyNombre() {
return nombreArte;
}
Y desde ahí recogerlo en el fragment con:
String nombreArte = activityId.getMyNombre();
((TextView) rootView.findViewById(R.id.nombreArteGeneral)).set Text(nombreArte);
Para eso paso el nombre de onPostExecute con:
delegate.processFinish(nombre);
y lo recojo en la Actividad con:
public void processFinish(String outnombre){
nombreArte=outnombre;
Toast.makeText(this, nombreArte, Toast.LENGTH_LONG).show();
}
El problema me surge en como pasar la variable (nombreArte) de este método (processFinish) a getMyNombre() pues el hilo principal ya se ha ejecutado y la variable nombreArte en getMyNombre() no existe, aunque en processFinish sí, de echo el Toast funciona perfectamente.
Resumiendo:
Quiero pasar el valor de la variable nombreArte de:
public void processFinish(String outnombre){
nombreArte=outnombre;
}
a:
public String getMyNombre() {
return nombreArte;
}
Para recogerla en el fragment con:
String nombreArte = activityId.getMyNombre();
((TextView) rootView.findViewById(R.id.nombreArteGeneral)).set Text(nombreArte);
Y lo que no funciona es que en:
public String getMyNombre() {
return nombreArte;
}
O pasarla y recogerla en el fragment de cualquier otra manera que se os ocurra.
Si alguien puede ayudarme se lo agradecería mucho, pues ando muy despistado.
  #2 (permalink)  
Antiguo 20/05/2016, 14:29
Avatar de racanix  
Fecha de Ingreso: diciembre-2008
Ubicación: Morelia Mich.
Mensajes: 192
Antigüedad: 15 años, 11 meses
Puntos: 8
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

¿Tu problema es que quieres comunicarte con los fragments? es decir Del fragment1 pasar datos al fragment 2?

Si es así utiliza un callback mediante interfaces y que puedan ser implementadas
en la activity.

Esta es una buena guia de la doc de android y desde mi punto de vista es la mejor
opcion, la otra es que utilizes metodos estaticos en los fragmentos pero esto seria
un poco sucio en cuestion de diseño.


https://developer.android.com/guide/...EventCallbacks

Sds
  #3 (permalink)  
Antiguo 23/05/2016, 02:45
 
Fecha de Ingreso: mayo-2014
Mensajes: 45
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

No no quiero pasar variables entre fragments. Tengo una actividad con adapter con dos fragmentes, y quiero pasar los valores de la actividad, que obtengo de una base de datos con Asyntask a los fragments.
  #4 (permalink)  
Antiguo 24/05/2016, 07:54
Avatar de racanix  
Fecha de Ingreso: diciembre-2008
Ubicación: Morelia Mich.
Mensajes: 192
Antigüedad: 15 años, 11 meses
Puntos: 8
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

Es muy similar a lo que te propuse anteriormente, desde la activity obtener
los fragments y pasa los datos obtenidos



Código:
public class MyActivity extends Activity{

  ...
   private Fragment1 fragment1;
   private FragmentManager fm;

   

  private void metodoAInvocarDesdeAsynkTask(final String parametro){

          if(fm == null){
                fm = getFragmentManager();
          }

          if(fragment1 == null){              
              fragment1 = fm.getFragmentByTag("TAG_MI_FRAGMENT");   
          }

          fragment1.ejecutarMetodo(parametro);


  }    
  ...

}



-----------------------------------------------------

class Fragment1 extends Fragment{

    TextView mTextView;
     ..... 

             public ejecutarMetodo(parametro){
                      mTextView.setText(parametro);
             }

     .....
}

Es simple desde tu activity obten una referencia del fragment que deseas ejeuctar su metodo.

Espero y te ayude

Sds
  #5 (permalink)  
Antiguo 24/05/2016, 16:46
 
Fecha de Ingreso: mayo-2014
Mensajes: 45
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

Quizá no me he explicado bien. El problema no es pasar las variables desde la actividad a unos fragments, que creo con un adapter. El problema es que en la Actividad que lleva el hilo principal tengo un Asyntask que se ejecuta en otro hilo y cuyos resultados, valores de variables, deben volver al hilo principal y de ahí al fragment. Pero el hilo principal (que maneja los fragments) se ejecuta, mientras el Asyntask sigue pensando y el valor que recojo con Callback "llega tarde".
Luego mi drama es como paso la variable que he recogido de onPostExecute y pasado a la actividad principal con el método:
public void processFinish(String outnombre){
nombreArte=outnombre;
}
y de ahí a cada uno de mis fragments.
Muchas gracias por el tiempo y la dedicación que me estás prestando.

Última edición por jlopezisern; 24/05/2016 a las 17:00
  #6 (permalink)  
Antiguo 25/05/2016, 11:38
Avatar de racanix  
Fecha de Ingreso: diciembre-2008
Ubicación: Morelia Mich.
Mensajes: 192
Antigüedad: 15 años, 11 meses
Puntos: 8
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

Vamos por partes,

Tu AsyncTask esta dentro de la Activity y ya obtienes las referencias de tus fragments.

Cita:
Pero el hilo principal (que maneja los fragments) se ejecuta, mientras el Asyntask sigue pensando y el valor que recojo con Callback "llega tarde".
pero no entiendo aque te refieres con que llega tarde, se supone que cuando AsycTask termina
tu debes llamar a los fragment y enviarle los datos, que en este caso es el ejemplo que te envie con la
llamada metodoAInvocarDesdeAsynkTask(), este metodo lo debes llamar en onPostExecute.


Ahora si tu estas cargando los fragments dentro de un TabAdapter ahi es otro tema, ya que
tendras que implementar una interfaz y por medio de esta pasar los datos.

Tambien estaria bien que compartieras tu codigo (identado) en como estas haciendo las llamadas o la implemetacion para que tengas una mayor ayuda del foro.

Sds
  #7 (permalink)  
Antiguo 27/05/2016, 04:16
 
Fecha de Ingreso: mayo-2014
Mensajes: 45
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

Estoy cargando los fragments dentro de un TabAdapter, en la actividad (ArteCulturaGeneral extends AppCompatActivity) tengo:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.arte_cultura_general);
Toolbar toolbar = (Toolbar) findViewById(R.id.appbarguiameartegenral);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(f alse);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpagerartegenral);
viewPager.setAdapter(new PagerAdapterArqueologia(
getSupportFragmentManager()));
getSupportActionBar().setDisplayShowTitleEnabled(f alse);
TabLayout tabLayout = (TabLayout) findViewById(R.id.appbartabsartegenral);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.setupWithViewPager(viewPager);
Y la clase ArteGeneralDetails extends AsyncTask. Para obtener los valores de la consulta a la base de datos en la actividad implemento una interfaz de la siguiente manera:
1 Creo la clase:
public interface AsyncResponse {
void processFinish(String output);
}
2 En la actividad:
public class ArteCulturaGeneral extends AppCompatActivity implements AsyncResponse{
ArteGeneralDetails asyncTask = new ArteGeneralDetails();

protected void onCreate(Bundle savedInstanceState) {
asyncTask.delegate = this;

asyncTask.execute();
y en la clase AsyncTask:
class ArteGeneralDetails extends AsyncTask<String, String, String> {
public AsyncResponse delegate = null;

protected void onPostExecute(String nombre) {
pDialog.dismiss();
delegate.processFinish(nombre);
}
La variable (nombre) la recojo con el método:
public void processFinish(String outnombre){
nombreArte=outnombre;
Toast.makeText(this, nombreArte, Toast.LENGTH_LONG).show();
} //El Toast funciona perfectamente
Ahora viene mi drama. Tenía la intención de pasar nombreArte al fragment con:
public String getMyNombre() {
return nombreArte;
}
Y en el fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.arte_general_arqueolog, container, false);
ArteCulturaGeneral activityId = (ArteCulturaGeneral) getActivity();
String nombreArte2 = activityId.getMyNombre();
((TextView) rootView.findViewById(R.id.nombreArteGeneral)).set Text(nombreArte2);
return rootView;
}
Lo cual no puede ser, aquí es donde no me he explicado bien con “no entiendo a que te refieres con que llega tarde”, lo que debería haber dicho es: estoy llamando al get antes de que la tarea haya acabado, y entonces el valor que espero todavía no está en la variable porque no se ha llamado todavía al processFinish. Luego por ahí no voy a ninguna parte y lo que me gustaría saber en como puedo pasar la variable del processFinish al fragment.
Gracias otra vez por tu ayuda.

Última edición por jlopezisern; 27/05/2016 a las 05:47
  #8 (permalink)  
Antiguo 27/05/2016, 09:36
Avatar de racanix  
Fecha de Ingreso: diciembre-2008
Ubicación: Morelia Mich.
Mensajes: 192
Antigüedad: 15 años, 11 meses
Puntos: 8
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

Ya esta más claro

Tu implementacón de llamar a la activity desde el fragment en esta ocación no te
servira ya que como lo comentas debes esperar a que tu proceso de ArteGeneralDetails termine. En su lugar debes llamar al fragment desde el activity
es decir en el metodo que pasas:

Código:
// Ejemplo
public void processFinish(String outnombre){
nombreArte=outnombre;
Toast.makeText(this, nombreArte, Toast.LENGTH_LONG).show();

// Se entiende que ya cuentas con una referencia de tu fragmento.
myFragment.establecerNombre(outnombre);
}
y en tu fragment declara ese metodo

Código:
public void establecerNombre(final String nombre){
// TODO: Lo que tengas que hacer con el nombre
}

De hece modo cuando tu tarea en segundo plano termine pasaras los datos
al fragment que es como te he comentado.

Espero que sirva

Un sds
  #9 (permalink)  
Antiguo 28/05/2016, 03:47
 
Fecha de Ingreso: mayo-2014
Mensajes: 45
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

Me pierdo, cuando dices // Se entiende que ya cuentas con una referencia de tu fragmento.
myFragment.establecerNombre(outnombre);

¿A qué te refieres?
  #10 (permalink)  
Antiguo 28/05/2016, 18:20
Avatar de racanix  
Fecha de Ingreso: diciembre-2008
Ubicación: Morelia Mich.
Mensajes: 192
Antigüedad: 15 años, 11 meses
Puntos: 8
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

A que debes obtener la referencia del Fragment, en este caso tu fragment esta en
un adapter para lo cual debes obtenerlo como lo sugiere esta solución

http://stackoverflow.com/questions/1...-the-viewpager

Suerte
  #11 (permalink)  
Antiguo 03/06/2016, 11:59
 
Fecha de Ingreso: mayo-2014
Mensajes: 45
Antigüedad: 10 años, 6 meses
Puntos: 0
Respuesta: Problema con AsyncTask, processFinish y el hilo principal.

Lo primero muchas gracias por tu tiempo y tus conocimientos, me has sido de mucha ayuda.
Ha sido un drama aclararme con los fragments, pero llevabas toda la razón cuando decías: “tu proceso de ArteGeneralDetails termine. En su lugar debes llamar al fragment desde el Activity” y “en tu fragment declara este método:
public void establecerNombre(final String nombre){
// TODO: Lo que tengas que hacer con el nombre
}
La solución es muy simple, pero joder que dolor de cabeza.
public void processFinish(String outnombre){
if (viewPager.getCurrentItem() == 0) {
Arqueolog fragmentarte = (Arqueolog)viewPager.getAdapter().instantiateItem( viewPager, viewPager.getCurrentItem());
fragmentArte.establecerNombre(outnombre);
} else if (viewPager.getCurrentItem() == 1) {
Mapa fragmentArteMapa = (Mapa)viewPager.getAdapter().instantiateItem(viewP ager, viewPager.getCurrentItem());
}
}

Etiquetas: hilo
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:25.