2010-07-28 13 views
5

En mi aplicación, a veces la excepción siguiente:Android: IllegalStateException - ¿Cuándo se lanza?

07-28 14:49:25.398: ERROR/AndroidRuntime(8097): 
java.lang.IllegalStateException: The content of the adapter has changed 
but ListView did not receive a notification. Make sure the content of 
your adapter is not modified from a background thread, but only from the 
UI thread. [in ListView(2131099717, class android.widget.ListView) with 
Adapter(class ch.uzh.csg.games4blue.gamebase.view.UserView$UserAdapter)] 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.ListView.layoutChildren(ListView.java:1432) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.AbsListView.onLayout(AbsListView.java:1113) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.layoutVertical(LinearLayout.java:998) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.onLayout(LinearLayout.java:918) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1108) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.onLayout(LinearLayout.java:920) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.FrameLayout.onLayout(FrameLayout.java:333) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.layoutVertical(LinearLayout.java:998) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.onLayout(LinearLayout.java:918) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.layoutVertical(LinearLayout.java:998) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.LinearLayout.onLayout(LinearLayout.java:918) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.FrameLayout.onLayout(FrameLayout.java:333) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.widget.FrameLayout.onLayout(FrameLayout.java:333) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.View.layout(View.java:6831) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.ViewRoot.performTraversals(ViewRoot.java:996) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.view.ViewRoot.handleMessage(ViewRoot.java:1633) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.os.Handler.dispatchMessage(Handler.java:99) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.os.Looper.loop(Looper.java:123) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
android.app.ActivityThread.main(ActivityThread.java:4338) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
java.lang.reflect.Method.invokeNative(Native Method) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
java.lang.reflect.Method.invoke(Method.java:521) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
07-28 14:49:25.398: ERROR/AndroidRuntime(8097):  at 
dalvik.system.NativeStart.main(Native Method) 

Es difícil encontrar el error, porque en el StackTrace ninguno de mis métodos aparece en la lista. Entonces, ¿alguien sabe cuándo se lanza esta excepción? Gracias por cualquier pista.

Respuesta

3

Se puede ver el error en su StackTrace:

El contenido del adaptador ha cambiado pero ListView no recibió una notificación . Asegúrese de que el contenido de su adaptador no se modifique desde un subproceso de fondo , sino solo desde el subproceso IU .

Debe buscar en uno de sus hilos y sincronizarlo con su hilo de interfaz de usuario.

La forma de hacer esto en Android es con Handler.

http://developer.android.com/guide/appendix/faq/commontasks.html#threading

+0

Michael B .Necesito su ayuda, en realidad también estoy obteniendo el mismo error aquí es la pregunta http://stackoverflow.com/questions/16477755/application-stops-on-changing-page –

2

Donde utiliza ch.uzh.csg.games4blue.gamebase.view.UserView$UserAdapter.

1

De hecho, este tipo de error se envía al modificar el contenido de su adaptador, sin notificar a su vista de lista o de cualquier otra vista usando un adaptador que su contenido debe ser actualizado.
Intente llamar al .notifyDataSetChanged() en el adaptador.

20

Te dice la clase en la que se produce el error en: ch.uzh.csg.games4blue.gamebase.view.UserView contiene una clase llamada UserAdapter dentro de ella.

Vamos a tratar de explicar lo que está sucediendo aquí - Cuando se crea un ListView con un Adapter respaldándolo, el ListView obtiene sus datos solicitando el adaptador para ello. Cada vez que se desplaza, ListView le pide al adaptador los nuevos elementos en los que se desplazó.

Normalmente crea el ListView, crea el adaptador, configura el adaptador en la vista de lista, y listo. Android OS se ocupa del resto. Lo que estás intentando hacer, sin embargo, es un poco más complicado. Está intentando ocasionalmente actualizar los datos en el adaptador. ¿Te imaginas que la lista debería ser informada si los datos del adaptador cambiaron, correcto? Si está mostrando una lista con 2 ítems, y de repente agrega 2 ítems más al adaptador, ¡la lista ahora debería mostrar 4 ítems! Sin embargo, sería realmente ineficiente si la vista de lista tuviera que estar continuamente revisando para ver si el adaptador ha cambiado, ¿no? Entonces, lo que debe suceder es que la vista de lista asuma que el adaptador no cambia, y el adaptador notificará a la vista de lista si cambia. (Este acuerdo entre la vista de lista y el adaptador permite otros beneficios, como la vista de lista puede almacenar en caché algunos de los elementos recuperados del adaptador para un acceso rápido. Aka, si hay 10 elementos de lista visualizados en la pantalla, la lista puede ya haber solicitado 14 elementos. De esta forma, si se desplaza hacia arriba o hacia abajo, al menos 2 elementos en cualquier dirección, el ListView ya tiene los datos para mostrar)

Lo que no ha podido hacer, sin embargo, es notificar a la lista que datos dentro del adaptador cambiados. ¡En algún lugar dentro de UserAdapter o UserView los datos están siendo cambiados! Para que esto sea fácil para todos, ¿quizás podrías publicar la clase completa de UserView? Mi apuesta es que tienes algún objeto de datos como ArrayList, como una variable privada dentro de la clase UserView.Dentro de la clase UserAdapter está proporcionando estos datos a ListView. Sin embargo, en algún lugar dentro de la clase UserView está modificando este conjunto de datos, después de que ya ha proporcionado al ListView.

responsabilidad: Lo que más me copiando otras respuestas aquí, pero creo que puedo ofrecer una visión más clara de lo que está sucediendo si combino las respuestas dadas 2-3

Disclaimer 2: estoy cansado y esto parece pobremente escrito. Convertirlo en una wiki con la esperanza de que alguien limpie mi desorden nocturno. Si esto es totalmente ininteligible sólo dilo y malos eliminarla

1

Tengo el mismo problema que enfrenta yo estaba usando asynchrousTask para llenar los datos en listview.I que resuelve reescribir el código que actualiza Ui en fn

  1. onPostExecute()
  2. OnPreExecute()

Debido a que estos función se ejecuta en hilo de interfaz de usuario.

Espero que esto ayude.

0

¡He solucionado esto!

Anteriormente fue realizar un procesamiento grande como este, donde list era estático y bajo la Clase de actividad:

@Override 
protected Void doInBackground(Void... arg0) { 
    for (int i=0; i<bigChunk.size(); i++) { 
     list.add(somethingHeavy(i)); 
    } 
} 

entonces hice una nueva lista, y ha añadido que, en:

List<YourObject> listToAdd; 
@Override 
protected Void doInBackground(Void... arg0) { 
    listToAdd = new ArrayList<YourObject>(); 
    for (int i=0; i<bigChunk.size(); i++) { 
     listToAdd.add(somethingHeavy(i)); 
    } 
} 
@Override 
protected void onPostExecute(Void result) { 
    list = listToAdd; 
    adapter.notifyDataSetChanged(); 
} 
Cuestiones relacionadas