Kar*_*pka 240 android android-layout screen-rotation android-recyclerview
我们的QA检测到一个错误:当旋转Android设备(Droid Turbo)时,发生以下与RecyclerView相关的崩溃:
java.lang.IndexOutOfBoundsException:检测到不一致.无效的项目位置2(偏移量:2).state:3
对我来说,它看起来像RecyclerView内部的一个内部错误,因为我无法想到这是由我们的代码直接导致的任何方式......
有谁遇到过这个问题?
什么是解决方案?
一个残酷的解决方法可能是在发生异常时捕获异常并从头开始重新创建RecyclverView实例,以避免陷入损坏状态.
但是,如果可能的话,我想更好地理解这个问题(并且可能在其源头修复它),而不是掩盖它.
这个bug很难重现,但是当它发生时它是致命的.
完整的堆栈跟踪:
W/dalvikvm(7546):threadid = 1:线程退出,未捕获异常(组= 0x41987d40)E/AndroidRuntime(7546):致命异常:主E/AndroidRuntime(7546):进程:com.oblong.mezzedroid,PID:7546 E/AndroidRuntime(7546):java.lang.IndexOutOfBoundsException:检测到不一致.无效的项目位置2(偏移量:2).state:3 E/AndroidRuntime(7546):在android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:3382)E/AndroidRuntime(7546):at android .support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:3340)E/AndroidRuntime(7546):at android.support.v7.widget.LinearLayoutManager $ LayoutState.next(LinearLayoutManager.java:1810)E/AndroidRuntime (7546):在android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1306)E/AndroidRuntime(7546):在android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1269)E/AndroidRuntime(7546):在android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:523)E/AndroidRuntime(7546):at org.liboid.recycler_view.RecyclerViewContainer $ LiLinearLayoutManager.onLayoutChildren(RecyclerViewContainer.java:179 )E/AndroidRuntime(7546):在android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1942))E/AndroidRuntime(7546):在android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2237)E/AndroidRuntime(7546):at org.liboid.recycler_view.LiRecyclerView.onLayout(LiRecyclerView.java:30) )E/AndroidRuntime(7546):在android.view.View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546) ):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)E/AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)E/AndroidRuntime(7546):在android.view .View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout) .java:453)E/AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)E/AndroidRuntime(7546):在android.view.View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)E/AndroidRuntime(7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)E/AndroidRuntime( 7546):在android.widget.LinearLayout.onLayout(LinearLayout.java:1434)E/AndroidRuntime(7546):at com.oblong.mezzedroid.workspace.content.bins.BinsContainerLayout.onLayout(BinsContainerLayout.java:22)E/AndroidRuntime(7546):在android.view.View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546):at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)E/AndroidRuntime(7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)E/AndroidRuntime(7546):在android.widget.LinearLayout. onLayout(LinearLayout.java:1434)E/AndroidRuntime(7546):在android.view.View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java: 4651)E/Android 运行时(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)E/AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)E/AndroidRuntime(7546):at android.view.View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546):在android.widget.FrameLayout. layoutChildren(FrameLayout.java:453)E/AndroidRuntime(7546):在android.widget.FrameLayout.onLayout(FrameLayout.java:388)E/AndroidRuntime(7546):在android.view.View.layout(View.java: 14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)E/AndroidRuntime( 7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)E/AndroidRuntime(7546):在android.widget.LinearLayout.onLayout(LinearLayout.java:1434)E/AndroidRuntime(7546):在android. view.View.layout(View.java:14946)E/Andro idRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)E/AndroidRuntime(7546):at android.widget.FrameLayout.onLayout(FrameLayout.java:388)E/AndroidRuntime(7546):在android.view.View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup. layout(ViewGroup.java:4651)E/AndroidRuntime(7546):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)E/AndroidRuntime(7546):在android.widget.LinearLayout.layoutVertical(LinearLayout.java: 1525)E/AndroidRuntime(7546):在android.widget.LinearLayout.onLayout(LinearLayout.java:1434)E/AndroidRuntime(7546):在android.view.View.layout(View.java:14946)E/AndroidRuntime( 7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime(7546):在android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)E/AndroidRuntime(7546):在android. widget.FrameLayout.onLayout(FrameLayout.java:3 88)E/AndroidRuntime(7546):在android.view.View.layout(View.java:14946)E/AndroidRuntime(7546):在android.view.ViewGroup.layout(ViewGroup.java:4651)E/AndroidRuntime( 7546):在android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2132)E/AndroidRuntime(7546):在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1872)E/AndroidRuntime(7546):at andro
小智 182
我有一个(可能)相关的问题 - 使用RecyclerView输入一个活动的新实例,但是使用较小的适配器为我引发了这个崩溃.
RecyclerView.dispatchLayout()在打电话之前可以尝试从废料中提取物品mRecycler.clearOldPositions().结果是它从公共池中拉出位置高于适配器大小的项目.
幸运的是,只有在启用了PredictiveAnimations时才会这样做,因此我的解决方案是继承GridLayoutManager(LinearLayoutManager具有相同的问题和'fix'),并覆盖supportsPredictiveItemAnimations()以返回false:
/**
* No Predictive Animations GridLayoutManager
*/
private static class NpaGridLayoutManager extends GridLayoutManager {
/**
* Disable predictive animations. There is a bug in RecyclerView which causes views that
* are being reloaded to pull invalid ViewHolders from the internal recycler stack if the
* adapter size has decreased since the ViewHolder was recycled.
*/
@Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
public NpaGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public NpaGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public NpaGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*ejC 77
在我的情况下(删除/插入我的数据结构中的数据)我需要清除回收池,然后通知数据集已更改!
mRecyclerView.getRecycledViewPool().clear();
mAdapter.notifyDataSetChanged();
kha*_*ntt 38
使用notifyDataSetChanged(),而不是notifyItem...在这种情况下.
Ram*_*rel 15
当用户滚动时适配器中的列表清除时会发生此错误,这使得项目持有者的位置发生变化,在 ui 上的列表和项目之间丢失了引用,错误发生在下一个 “notifyDataSetChanged”请求中。
使固定:
查看您的更新列表方法。如果你做类似的事情
mainList.clear();
...
mainList.add() or mainList.addAll()
...
notifyDataSetChanged();
===> Error occur
Run Code Online (Sandbox Code Playgroud)
怎么修。为缓冲区处理创建新的列表对象,然后再次分配给主列表
List res = new ArrayList();
…..
res.add(); //add item or modify list
….
mainList = res;
notifyDataSetChanged();
Run Code Online (Sandbox Code Playgroud)
感谢Nhan Cao的大力帮助 :)
Oda*_*aym 11
我通过mRecycler.setAdapter(itemsAdapter)将所有项目添加到适配器后将延迟延迟解决了这个问题mRecycler.addAll(items)并且工作正常.我不明白为什么我这样做,它来自我看过的图书馆代码,看到那些"错误的顺序",我很确定这是它,如果有人可以确认它解释为什么它是所以?不确定这是否是一个有效的答案
Aal*_*lap 11
我有类似的问题,但不完全一样.在我的情况下,1点我正在清理传递给recyclerview的数组
mObjects.clear();
Run Code Online (Sandbox Code Playgroud)
而不是调用notifyDataSetChanged,因为我不希望recyclerview立即清除视图.我在AsyncTask中重新填充了mObjects数组.
对我来说,添加这行代码后它就起作用了:
mRecyclerView.setItemAnimator(null);
Run Code Online (Sandbox Code Playgroud)
我有同样的问题.当我快速滚动并调用API并更新数据时,就会发生这种情况.在尝试所有事情以防止崩溃之后,我找到了解决方案.
mRecyclerView.stopScroll();
Run Code Online (Sandbox Code Playgroud)
它会工作.
我正在RecyclerView后台更改数据Thread。我Exception和OP一样。我在更改数据后添加了这个:
myRecyclerView.post(new Runnable() {
@Override
public void run() {
myRecyclerAdapter.notifyDataSetChanged();
}
});
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你
就我而言,我正在更新项目并调用notifyDataSetChanged非 UI 线程。大多数时候它都有效,但是当大量变化快速发生时,它就会崩溃。当我这样做时,基本上
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
changeData();
notifyDataSetChanged();
}
});
Run Code Online (Sandbox Code Playgroud)
然后它就停止崩溃了。
在我修改Adapter实现以使用 items 数组的副本而不是引用后,我的问题就消失了。setItems()每当我们有新项目要在 中显示时,就会调用该方法RecyclerView。
代替:
private class MyAdapter extends RecyclerView.Adapter<ItemHolder> {
private List<MyItem> mItems;
(....)
void setItems(List<MyItem> items) {
mItems = items;
}
}
Run Code Online (Sandbox Code Playgroud)
我做了:
void setItems(List<MyItem> items) {
mItems = new ArrayList<>(items);
}
Run Code Online (Sandbox Code Playgroud)
我在recyclerView上遇到了同样的问题,所以我只是在清除列表后立即通知适配器有关数据集更改的信息。
mList.clear();
mAdapter.notifyDataSetChanged();
mList.addAll(newData);
mAdapter.notifyDataSetChanged();
Run Code Online (Sandbox Code Playgroud)
这是唯一对我有用的解决方案,即使尝试了上面的许多解决方案。
1.) 实用化
CustomAdapter scrollStockAdapter =
new CustomAdapter(mActivity, new ArrayList<StockListModel>());
list.setAdapter(scrollStockAdapter);
scrollStockAdapter.updateList(stockListModels);
Run Code Online (Sandbox Code Playgroud)
2.)将此方法写入适配器中
public void updateList(List<StockListModel> list) {
stockListModels.clear();
stockListModels.addAll(list);
notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)
stockListModels -> 此列表是您在适配器中使用的列表。
| 归档时间: |
|
| 查看次数: |
102194 次 |
| 最近记录: |