05-
05 11:
47:
52.021 4882-
4882/
com.daijintao.youjin E/AndroidRuntime: FATAL EXCEPTION: main
Process:
com.daijintao.youjin, PID:
4882
java
.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{
184736a1 position=
1 id=-
1, oldPos=
1, pLpos:-
1 scrap [attachedScrap] tmpDetached no parent}
at android
.support.v7
.widget.RecyclerView$Recycler
.validateViewHolderForOffsetPosition(RecyclerView
.java:
5297)
at android
.support.v7
.widget.RecyclerView$Recycler
.tryGetViewHolderForPositionByDeadline(RecyclerView
.java:
5479)
at android
.support.v7
.widget.RecyclerView$Recycler
.getViewForPosition(RecyclerView
.java:
5440)
at android
.support.v7
.widget.RecyclerView$Recycler
.getViewForPosition(RecyclerView
.java:
5436)
at android
.support.v7
.widget.LinearLayoutManager$LayoutState
.next(LinearLayoutManager
.java:
2224)
at android
.support.v7
.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager
.java:
1551)
at android
.support.v7
.widget.LinearLayoutManager.fill(LinearLayoutManager
.java:
1511)
at android
.support.v7
.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager
.java:
595)
at android
.support.v7
.widget.RecyclerView.dispatchLayoutStep1(RecyclerView
.java:
3534)
at android
.support.v7
.widget.RecyclerView.onMeasure(RecyclerView
.java:
3019)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.LinearLayout.measureChildBeforeLayout(LinearLayout
.java:
1436)
at android
.widget.LinearLayout.measureVertical(LinearLayout
.java:
722)
at android
.widget.LinearLayout.onMeasure(LinearLayout
.java:
613)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.LinearLayout.measureChildBeforeLayout(LinearLayout
.java:
1436)
at android
.widget.LinearLayout.measureVertical(LinearLayout
.java:
722)
at android
.widget.LinearLayout.onMeasure(LinearLayout
.java:
613)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.LinearLayout.measureChildBeforeLayout(LinearLayout
.java:
1436)
at android
.widget.LinearLayout.measureVertical(LinearLayout
.java:
722)
at android
.widget.LinearLayout.onMeasure(LinearLayout
.java:
613)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.FrameLayout.onMeasure(FrameLayout
.java:
436)
at android
.support.v7
.widget.ContentFrameLayout.onMeasure(ContentFrameLayout
.java:
139)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.LinearLayout.measureChildBeforeLayout(LinearLayout
.java:
1436)
at android
.widget.LinearLayout.measureVertical(LinearLayout
.java:
722)
at android
.widget.LinearLayout.onMeasure(LinearLayout
.java:
613)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.FrameLayout.onMeasure(FrameLayout
.java:
436)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.LinearLayout.measureChildBeforeLayout(LinearLayout
.java:
1436)
at android
.widget.LinearLayout.measureVertical(LinearLayout
.java:
722)
at android
.widget.LinearLayout.onMeasure(LinearLayout
.java:
613)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewGroup.measureChildWithMargins(ViewGroup
.java:
5535)
at android
.widget.FrameLayout.onMeasure(FrameLayout
.java:
436)
at
com.android.internal.policy.impl.PhoneWindow$DecorView
.onMeasure(PhoneWindow
.java:
2615)
at android
.view.View.measure(View
.java:
17547)
at android
.view.ViewRootImpl.performMeasure(ViewRootImpl
.java:
2015)
at android
.view.ViewRootImpl.measureHierarchy(ViewRootImpl
.java:
1173)
at android
.view.ViewRootImpl.performTraversals(ViewRootImpl
.java:
1379)
at android
.view.ViewRootImpl.doTraversal(ViewRootImpl
.java:
1061)
at android
.view.ViewRootImpl$TraversalRunnable
.run(ViewRootImpl
.java:
5885)
at android
.view.Choreographer$Callb
这么晚了还在调试BUG实在伤不起,不过作为一个准程序员来说这点幸苦当然算不了什么。现在把今天碰到的一个比较令人不解的错误记录下来,以备日后随时翻查。 这么长一串异常信息实在很令人头疼,因为异常的地方根本没有跟自己的代码无关,所以在看了几个错误之后我放弃了,果断度娘。在几经搜索之后,终于在一篇博文中搜到了结果,这里我就引用下网上大神的原话:
文章中说到:在进行数据移除和数据增加时,务必要保证RVAdapter中的数据和移除的数据保持一致!什么意思呢?我自己琢磨认为是这样的,如果你更新你的集合后,调用RVAdapter的新出现的notifyxxxx方法时,adapter 的更新预期结果和实际集合更新结果不同,那么就会出现异常了。 举个例子吧: 比如你集合remove了两条数据,但是你RVAdapter只notifyItemRemoved(2)(这里表示移除第三条数据,只移除了一条),这种情况旧属于数据不一致了。还有一种是你增加数据,你集合增加10条数据,但是你RVAdapter的notify只增加了5条数据,这也是数据不一致。 好了,通过以上两种情况,大概就知道了,这个数据一致其实说的是要保证数量一致。就是说RVAdapter有个size,你的集合有个size。这两个size,在调用RvAdapter的notifyxxxx时候必须保持相同。
看到这里,似乎茅塞顿开,去翻看自己的代码,果然在一个不起眼的位置发现了异常。
editText.addTextChangedListener(
new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s,
int start,
int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s,
int start,
int before,
int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().equals(
"")) {
ryHint.setVisibility(View.GONE);
searchList.clear();
hintAdapter.notifyItemChanged(
0);
}
else {
loadYoujinData(s.toString());
}
}
});
当我们清空输入内容的时候会执行if语句的第一个判断,这里的hintAdapter调用了notifyItemChanged(0)这个方法,然后是loadYoujiData这个方法的内容,这个方法是根据输入内容去请求网络数据,以下是这个方法里的关键部分,这里我使用了Bmob后端云作为我的云端服务器。
youjinBmobQuery
.findObjects(new FindListener<Youjin>() {
@Override
public void done(List<Youjin> list, BmobException e) {
if (e == null) {
if (list
.size() ==
0) {
//返回数据大小为
0
Toast
.makeText(MainActivity
.this,
"数据不存在", Toast
.LENGTH_SHORT)
.show()
} else {
ryHint
.setVisibility(View
.VISIBLE)
//设置RecyclerView
searchList
.clear()
searchList
.addAll(list)
for(Youjin youjin:searchList){
Log
.i(
"TAG",youjin
.getName())
}
hintAdapter
.notifyDataSetChanged()
}
} else {
Toast
.makeText(MainActivity
.this,
"加载错误", Toast
.LENGTH_SHORT)
.show()
Log
.i(
"TAG",
"加载错误:" + e
.getMessage()
.toString())
}
可以看到这里的adapter使用了notifyDataSetChaned(); 这样写导致的结果就是两次notifyXXX时所更新的数据和实际不一致,当我把两个调用notifyXXX的地方对调notifyXXX方法后发现错误仍然存在,而两处调用同一个notify方法,异常却没有了。
以上只是我个人的看法,欢迎大家多多指点,指出错误的地方,让小弟我及时查漏补缺。