异常一
参考网页
异常堆栈信息
06-27 16:49:50.463 E/AndroidRuntime(20889): FATAL EXCEPTION: main
06-27 16:49:50.463 E/AndroidRuntime(20889): Process: a, PID: 20889
06-27 16:49:50.463 E/AndroidRuntime(20889): java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2349)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:4551)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:10366)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:6044)
06-27 16:49:50.463 E/AndroidRuntime(20889): at a.gui.adapters.TrackAdapters.QueueTrackAdapter$TrackViewHolder.onItemClear(QueueTrackAdapter.java:522)
06-27 16:49:50.463 E/AndroidRuntime(20889): at a.gui.adapters.swipedrag.SimpleItemTouchHelperCallback.clearView(SimpleItemTouchHelperCallback.java:124)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.helper.ItemTouchHelper.onChildViewDetachedFromWindow(ItemTouchHelper.java:876)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.dispatchChildDetached(RecyclerView.java:6234)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.access$1200(RecyclerView.java:151)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView$5.removeViewAt(RecyclerView.java:651)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.ChildHelper.removeViewAt(ChildHelper.java:168)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView$LayoutManager.removeViewAt(RecyclerView.java:7092)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView$LayoutManager.scrapOrRecycleView(RecyclerView.java:7638)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView$LayoutManager.detachAndScrapAttachedViews(RecyclerView.java:7624)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:546)
06-27 16:49:50.463 E/AndroidRuntime(20889): at a.gui.activities.QueueActivity$WrapContentLinearLayoutManager.onLayoutChildren(QueueActivity.java:359)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3260)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3069)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1478)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1542)
06-27 16:49:50.463 E/AndroidRuntime(20889): at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2649)
......
......
06-27 16:49:50.464 E/AndroidRuntime(20889): at android.os.Handler.handleCallback(Handler.java:836)
06-27 16:49:50.464 E/AndroidRuntime(20889): at android.os.Handler.dispatchMessage(Handler.java:103)
06-27 16:49:50.464 E/AndroidRuntime(20889): at android.os.Looper.loop(Looper.java:203)
06-27 16:49:50.464 E/AndroidRuntime(20889): at android.app.ActivityThread.main(ActivityThread.java:6347)
06-27 16:49:50.464 E/AndroidRuntime(20889): at java.lang.reflect.Method.invoke(Native Method)
06-27 16:49:50.464 E/AndroidRuntime(20889): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
06-27 16:49:50.464 E/AndroidRuntime(20889): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
如何复现
左滑或右滑删除Item的时候,调用了notifyDataSetChanged来刷新数据源。
如何解决
简书的文章中将notifyDataSetChanged();
方法的调用放到Handler中,问题得到解决。
问题(FIXME)
为什么在ListView中不会出现这个问题?
RecyclerView抛出这个异常是为了避免什么?
异常二
参考网页
- RecyclerView内部BUG: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position
- RecyclerView系列(4)—XRexyclerView的坑,java.lang.IndexOutOfBoundsException: Inconsistency detected
异常堆栈信息
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3300)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:3258)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1803)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1302)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1265)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1093)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:956)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:2715)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:524)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
at dalvik.system.NativeStart.main(Native Method)
如何复现
我看两篇文章也没有太搞清楚异常是为什么报出来的,大概就是添加或者删除item的时候导致的不一致,致使内部报错。
如何解决
复写一个WrapLayoutManager捕获异常
public class WrapContentLinearLayoutManager extends LinearLayoutManager {
public WrapContentLinearLayoutManager(Context context) {
super(context);
}
public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public WrapContentLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
调用
mRecyclerView.setLayoutManager(new WrapContentLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
问题(FIXME)
- 为什么ListView没有出现这个问题?
- 我自己的项目中,adapter和外部操作的是同一个ArrayList,还是会报错,为什么RecyclerView会这样处理,出现明显的错误,难道有其他的调用方式?
- 我甚至在一个网页上看到有人说RecyclerView每隔1s更新一下任务太繁重了?手机的处理应该是毫秒级的,何来繁重?
文档信息
- 本文作者:itlgl
- 本文链接:https://itlgl.com/note/2024/04/19/2018-10-11-issues-26/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)