2011-11-27 9 views
19

Recientemente convertí mis actividades en fragmentos.Fragmentos que se reemplazan mientras se ejecuta AsyncTask - NullPointerException en getActivity()

Utilizando algo similar a Tab-Navigation, los fragmentos se reemplazan cuando el usuario selecciona otra pestaña. Después de llenar el fragmento, comienzo al menos una AsyncTask para obtener información de Internet. Sin embargo - si el usuario cambia a otra ficha al igual que se está ejecutando el doBackground método de mi AsyncTask - el fragmento se reemplazado y por lo tanto estoy consiguiendo un NullPointerException en las líneas marcadas:

@Override 
protected Object doInBackground(Object... params) { 
    ... 
    String tempjson = helper.SendPost(getResources().getText(R.string.apiid)); //ERROR: Fragment not attached 
    ... 
} 

protected onPostExecute(Object result) { 
    ... 
    getActivity().getContentResolver() //NULLPOINTEREXCEPTION 
    getView().findViewById(R.id.button) //NULL 
    ... 
} 

getActivity() y getResources() causa un error porque mi Fragmento es reemplazado.

cosas que he intentado:

  • Calling cancelar método en mi AsyncTask (no solucionará primer error ni el segundo error si se sustituye el fragmento mientras se ejecuta onPostExecute())
  • comprobar si getActivity() es null o llamando this.isDetached() (no una solución real y que había necesidad de comprobar que cada vez que llamo getActivity() y así sucesivamente)

Entonces mi pregunta es: ¿cuál sería el mejor para deshacerse de estos problemas AsyncTask? No tuve estos problemas al usar Actividades ya que no fueron "eliminados"/separados en el cambio de pestaña (lo que resultó en un mayor uso de memoria - la razón por la que me gusta cambiar a Fragmentos)

Respuesta

18

Dado que AsyncTask se está ejecutando en segundo plano , su fragmento puede separarse de su actividad principal cuando finaliza. Como ya descubrió, puede usar isDetached() para verificar. No hay nada de malo en eso, y no tienes que controlarlo todo el tiempo, solo considera el fragmento y los ciclos de vida de la actividad. otros

dos alternativas:

  • Uso cargadoras, que están diseñados para jugar mejor con fragmentos
  • Mueva su carga AsyncTask a las interfaces de actividad de los padres y de uso para desacoplarse de los fragmentos. La actividad sabría si un fragmento está allí o no y actuará en consecuencia (descartando posiblemente el resultado si el fragmento se ha ido).
+8

que puedes usar isDetached() solo si se desprendió explícitamente el fragmento usted mismo. De lo contrario, debe usar isAdded() para manejar los casos en que el sistema destruyó el vínculo entre su actividad y su fragmento. – pcans

+0

@Nikolay Elenkov ¿cómo el ciclo de vida puede evitar la comprobación cada vez antes de llamar a getactivity? – Bear

-1

¿Has intentado llamar al setRetainInstance(true); en la función onCreate() de tu clase de fragmento?

+1

Esto no ayuda en este caso, los problemas son los mismos. Por ahora lo resolví creando campos para la actividad y visualicándolos y configurándolos en 'onActivityCreated()' usando 'view = getView()' y más. – Boni2k

4

Hoy me he enfrentado al mismo problema: cuando cambié la fragment se muestra si el AsyncTask no ha terminado todavía, y que intenta acceder a la view poblarlo con algunos elementos más, sería devolver un NullPointerException.

Resolví el problema anulando un método del ciclo de vida de los fragmentos: onDetach(). Este método se llama en el momento antes de que el fragment se separe del activity.

Lo que necesita hacer es llamar al método cancel() en su AsyncTask.Esto detendrá la ejecución de la tarea para evitar el NullPointerExecption.

He aquí una muestra de onDetach():

@Override 
public void onDetach() { 
    super.onDetach(); 
    task.cancel(true); 
} 

Marque esta página para obtener más información acerca de fragmentos del ciclo de vida: http://developer.android.com/reference/android/app/Fragment.html#Lifecycle Y esto para ver más sobre Cancelación de una tarea: http://developer.android.com/reference/android/os/AsyncTask.html

+0

Gracias, muchas gracias. ¡Esto solucionó mi problema que me había estado plagando durante una semana! –

Cuestiones relacionadas