android - java.lang.IllegalStateException: el contenido del adaptador ha cambiado pero ListView... a pesar de llamar notifydatasetchanged()
android-asynctask listactivity (4)
2) ¿En qué casos debo actualizar los contenidos de la actividad de la lista? dentro de doInBackground () o onProgressUpdate ()?
Dentro de onProgressUpdate()
o dentro de onPostExecute () porque puede llevar un tiempo desde que cambia el contenido en doInBackground()
y llama a las llamadas asincrónicas
@Override
protected void onPostExecute(String networkStatus) {
adapter.notifyDataSetChanged();
}
3) Estoy experimentando bloqueos regulares cuando el usuario hace clic en el elemento de la lista. Entonces, ¿desactivar el clic de eventos en la lista de actividades durante la operación de fondo resuelve el problema? Si es así, no estoy seguro de cómo eliminar o configurar el elemento, haga clic en los oyentes de forma dinámica a la actividad de la lista. Por favor, enséñame en el también.
No es una solución. Solo necesita actualizar su conjunto de datos en el hilo de UI. (No carga contenido, solo actualiza de viejo a uno nuevo). Por ejemplo
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected List<String> doInBackground(String... params) {
List<String> items = loadUpdatedDataset(params);
return items;
}
@Override
protected void onPostExecute(List<String> loadedItems) {
updateAdapterDataset(loadedItems);
adapter.notifyDataSetChanged();
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
¿Cuáles son las mejores prácticas que deben seguirse para actualizar los contenidos de una lista mediante un hilo de fondo (tarea asincrónica)?
1) Llamo a notifyDataSetChanged () para actualizar el adaptador tan pronto como manipulo el contenido del adaptador, pero la fuerza de mi aplicación se cierra mientras el usuario se desplaza o hace clic en la lista. Cualquier sugerencia para evitar esto sería muy útil.
Logcat: java.lang.IllegalStateException: el contenido del adaptador ha cambiado, pero ListView no recibió una notificación.
2) ¿En qué casos debo actualizar los contenidos de la actividad de la lista? dentro de doInBackground () o onProgressUpdate ()?
3) Estoy experimentando bloqueos regulares cuando el usuario hace clic en el elemento de la lista. Entonces, ¿desactivar el clic de eventos en la lista de actividades durante la operación de fondo resuelve el problema? Si es así, no estoy seguro de cómo eliminar o configurar el elemento, haga clic en los oyentes de forma dinámica a la actividad de la lista. Por favor, enséñame en el también.
4) No creo que el bloqueo de todas las interacciones de la ui durante la ejecución de la tarea asincrónica de fondo sea la única forma de resolver el problema. Sé que hay una manera simple de hacer esto pero necesito ayuda.
Gracias por adelantado.
Este es mi onCreate ...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fa);
tvStatus=(TextView) findViewById(R.id.tvStatus);
adapter = new SimpleAdapter(
this,
mostPopularList,
R.layout.list_item,
new String[] {"title","author","views","date"},
new int[] {R.id.textView1,R.id.textView2,R.id.textView4,R.id.textView3});
//populateList();
setListAdapter(adapter);
}
Mi tarea asincrónica ...
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
// code for adding new listactivty items
}
@Override
protected void onPostExecute(String networkStatus) {
adapter.notifyDataSetChanged();
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
Logcat:
raramente la excepción ilegal también ... no puedo reproducirla. publicará el logcat si vuelvo a encontrarlo.
FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 7, size is 4
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
at java.util.ArrayList.get(ArrayList.java:311)
at android.widget.SimpleAdapter.bindView(SimpleAdapter.java:147)
at android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:126)
at android.widget.SimpleAdapter.getView(SimpleAdapter.java:114)
at android.widget.AbsListView.obtainView(AbsListView.java:1294)
at android.widget.ListView.makeAndAddView(ListView.java:1727)
at android.widget.ListView.fillDown(ListView.java:652)
at android.widget.ListView.fillGap(ListView.java:623)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:2944)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:2065)
at android.widget.ListView.onTouchEvent(ListView.java:3315)
at android.view.View.dispatchTouchEvent(View.java:3766)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
Esta excepción es engañosa: hay muchas causas. Una de las causas de este bloqueo es que el objeto ArrayList no puede cambiar completamente. Entonces, cuando elimine un artículo, debo hacer esto:
mList.clear();
mList.addAll(newDataList);
Esto solucionó el problema por mí.
Por favor, compruébalo en esta clase. Hay un gran ejemplo usando AsyncTask y Listview http://android.okhelp.cz/java_android_code.php?o=%5Candroid-15%5CGestureBuilder%5Csrc%5Ccom%5Candroid%5Cgesture%5Cbuilder%5CGestureBuilderActivity.java#Problem .
Creo que el problema en su código se debe a que el adaptador está actualizando su ListView y en este momento el usuario hace clic en el ListView causando el bloqueo en su aplicación.
Este problema me molesta por mucho tiempo.
Cuando uso MotionEvent
para hacer clic en listView
antes de invocar Adapter.notifyDataSetChanged()
, se produce una excepción Illegalstate .
Así que creo que es útil invocar ListView.setEnable
(false) antes de actualizar listView
.