A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  问题描述
  Fabric上报的bug,一开始的时候不知道问题出在哪里,然后每个用到RecyclerView的地方都排查了一下终于找到了复现的步骤。
  有一个列表支持左右滑动删除,Item的布局里面也有删除按钮,点击之后有删除的动画,然后在动画结束的监听里面调用了adapter.notifyItemRemoved()方法。复现步骤是:在执行删除Item动画的时候立即上下滑动RecyclerView,必崩。
  Fabric上详细错误信息如下:
[C++] 纯文本查看 复制代码
Fatal Exception: java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder{4244ca70 position=0 id=-1, oldPos=-1, pLpos:-1 not recyclable(1)}
     at android.support.v7.widget.RecyclerView$5.attachViewToParent(RecyclerView.java:719)
     at android.support.v7.widget.ChildHelper.attachViewToParent(ChildHelper.java:239)
     at android.support.v7.widget.RecyclerView.addAnimatingView(RecyclerView.java:1222)
     at android.support.v7.widget.RecyclerView.animateDisappearance(RecyclerView.java:3594)
     at android.support.v7.widget.RecyclerView$4.processDisappeared(RecyclerView.java:485)
     at android.support.v7.widget.ViewInfoStore.process(ViewInfoStore.java:244)
     at android.support.v7.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3444)
     at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3194)
     at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1593)
     at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:323)
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
     at android.view.Choreographer.doCallbacks(Choreographer.java:591)
     at android.view.Choreographer.doFrame(Choreographer.java:559)
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
     at android.os.Handler.handleCallback(Handler.java:808)
     at android.os.Handler.dispatchMessage(Handler.java:103)
     at android.os.Looper.loop(Looper.java:193)
     at android.app.ActivityThread.main(ActivityThread.java:5292)
     at java.lang.reflect.Method.invokeNative(Method.java)
     at java.lang.reflect.Method.invoke(Method.java:515)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
     at dalvik.system.NativeStart.main(NativeStart.java)

  可能的原因
  根据Google Issue Tracker #37045161 上面的解释,当Item发生改变的时候,改变的动画会创建两份ViewHolder,旧的ViewHolder 淡出,新的ViewHolder 淡入。当我们想要重用这个ViewHolder 的时候,如果动画刚结束,ViewHolder 还没来得及回收,传递给RecyclerView的就是一个已经存在的ViewHolder ,这就导致了以上的问题。
  虽然看人家这么说是这个原因,但是没看过源码还是搞不明白,等有空把RecyclerView的源码研究研究再说吧。
  My Solution
  根据 samebug上推荐的答案,将notifyItemRemoved()方法替换成了notifyDataSetChanged(),bug解决。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马