viewholder有一个textview和imageview
textview显示用户姓名
imageview显示用户头像
在onbindviewholder时会根据item的id向服务器请求该用户的信息
由于请求是异步的,当请求成功回调设置textview和imageview的时候列表插入新信息,就会报错
错误信息如下:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{a2d62b7 position=2 id=-1, oldPos=1, pLpos:1 scrap [attachedScrap] tmpDetached no parent}
at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5046)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5177)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5158)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2061)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1445)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1408)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:580)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3330)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3186)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3632)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1799)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15718)
at android.view.ViewGroup.layout(ViewGroup.java:5039)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2129)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1886)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1103)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5949)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
at android.view.Choreographer.doCallbacks(Choreographer.java:601)
at android.view.Choreographer.doFrame(Choreographer.java:571)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5308)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:913)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:708)
The error message is insufficient and it is impossible to determine the cause.
All asynchronous image loading frameworks will not consider the following issue:
Both AdapterView and RecyclerView have a view reuse mechanism. The reused view must be a view with the same ItemViewType. Since the ItemViewType is the same, the processing logic of the user code should be the same.
If you implement a set of asynchronous image loading framework, you can refer to the Android official website document: Processing Bitmaps Off the UI Thread
In addition, it is not recommended to occupy the tag attribute of View, because you may need to use the tag for other purposes.
You are reporting an error because you are updating the interface in a non-UI thread...
In order to prevent image confusion during asynchronous loading, you can add a tag to the view and decide whether to load it based on the tag after the asynchronous task is completed.
This method should first determine whether there is a local cache, and if not, obtain it from the server. After the acquisition is completed, update the data corresponding to the adapter and update the list.