RecyclerView se desliza hacia arriba y hacia abajo rápidamente, análisis de causas de fallas y solución
- Registro de excepciones:
java.lang.IndexOutOfBoundsException: incoherencia detectada. Posición del elemento no válida
--------- beginning of crash
05-31 16:03:37.218 E/AndroidRuntime(21081): FATAL EXCEPTION: main
05-31 16:03:37.218 E/AndroidRuntime(21081): Process: com.xxx.xxx, PID: 21081
05-31 16:03:37.218 E/AndroidRuntime(21081): java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 9(offset:9).state:12 com.xxx.ugc.feeds.widget.ExtendedRecyclerView{
13be059 VFED..... ........ 0,0-1440,2235 #7f0a12ca app:id/recyclerView}, adapter:com.xxx.ugc.feeds.widget.ExtendedRecyclerView$HeaderViewListAdapter@2d7ce9f, layout:com.xxx.ugc.feeds.view.adapter.RecyclerViewNoBugLinearLayoutManager@4d19bec, context:com.xxx.xxxhd.home.ui.MainActivity@1ca5c38
05-31 16:03:37.218 E/AndroidRuntime(21081): at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5923)
05-31 16:03:37.218 E/AndroidRuntime(21081): at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:286)
05-31 16:03:37.218 E/AndroidRuntime(21081): at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:343)
05-31 16:03:37.218 E/AndroidRuntime(21081): at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:359)
05-31 16:03:37.218 E/AndroidRuntime(21081): at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:366)
05-31 16:03:37.218 E/AndroidRuntime(21081): at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:397)
05-31 16:03:37.218 E/AndroidRuntime(21081): at android.os.Handler.handleCallback(Handler.java:938)
05-31 16:03:37.218 E/AndroidRuntime(21081): at android.os.Handler.dispatchMessage(Handler.java:99)
05-31 16:03:37.218 E/AndroidRuntime(21081): at android.os.Looper.loop(Looper.java:223)
05-31 16:03:37.218 E/AndroidRuntime(21081): at android.app.ActivityThread.main(ActivityThread.java:7664)
05-31 16:03:37.218 E/AndroidRuntime(21081): at java.lang.reflect.Method.invoke(Native Method)
05-31 16:03:37.218 E/AndroidRuntime(21081): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(
- Reproducir la escena
En la escena RecyclerView anidada que usa SwipeRefreshLayout, la página admite la actualización desplegable (Actualizar) y deslizar hacia arriba para cargar más (LoadMore).
Primero tire rápidamente hacia abajo para actualizar la página, luego deslícese rápidamente hacia la página y finalmente active la carga de más operaciones. En este momento, la página tiene 2 cargas, una es para actualizar la carga y la otra es para cargar más carga. En este momento, es muy fácil que aparezca el bloqueo anterior: IndexOutOfBoundsException: incoherencia detectada. Posición del elemento no válida
- análisis del problema
Al tirar hacia abajo para actualizar, el conjunto de datos (ArrayList) se borrará y se ejecutará la operación Borrar.
Cuando deslice hacia arriba para cargar más, los datos se agregarán al conjunto de datos.
Al borrar los datos, no ejecutar la notificación de DataSetChanged causará este problema
4. Soluciones
Al borrar los datos, debe ejecutar la operación de notificación de conjunto de datos para notificar al adaptador que el conjunto de datos ha cambiado . De lo contrario, el adaptador no sabe que el conjunto de datos ha cambiado y habrá problemas en el cálculo de la posición.
Código puede referirse a:
dataList.clear();
notifyDataSetChanged();