RecyclerView报错:Scrapped or attached views may not be recycled

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/murphykwu/article/details/79137905

背景

RecyclerView由于需要处理大量数据,它的ViewHolder经常会复用,在性能提高的同时也有可能导致某些View的状态异常,导致JE问题。

log:

java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:true android.support.v7.widget.RecyclerView{3387b42 VFED..... .F...... 0,864-1080,1677 #7f0e0130 app:id/laps_list}, adapter:com.transsion.deskclock.stopwatch.LapsAdapter@f26659f, layout:android.support.v7.widget.LinearLayoutManager@e49e6ec, context:com.transsion.deskclock.DeskClock@b390471
android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:5887)
android.support.v7.widget.RecyclerView.removeAnimatingView(RecyclerView.java:1350)
android.support.v7.widget.RecyclerView$ItemAnimatorRestoreListener.onAnimationFinished(RecyclerView.java:12015)
android.support.v7.widget.RecyclerView$ItemAnimator.dispatchAnimationFinished(RecyclerView.java:12515)
android.support.v7.widget.SimpleItemAnimator.dispatchMoveFinished(SimpleItemAnimator.java:293)
android.support.v7.widget.DefaultItemAnimator$6.onAnimationEnd(DefaultItemAnimator.java:311)
android.view.ViewPropertyAnimator$AnimatorEventListener.onAnimationEnd(ViewPropertyAnimator.java:1122)
android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1209)
android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1449)
android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
android.animation.AnimationHandler.-wrap2(Unknown Source:0)
android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
android.view.Choreographer$CallbackRecord.run(Choreographer.java:922)
android.view.Choreographer.doCallbacks(Choreographer.java:732)
android.view.Choreographer.doFrame(Choreographer.java:661)
android.view.Choreographer$FrameDisplayEventReceiver.

解法

/frameworks/support/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java

void recycleViewHolderInternal(ViewHolder holder) {
     if (holder.isScrap() || holder.itemView.getParent() != null) {
     //这里重新判断一下,如果要复用的ViewHolder还没有detach,那就从parent里面移除好了。
        if ((holder.itemView.getParent() != null) 
        && (holder.itemView.getParent() instanceof ViewGroup)) {
            ViewGroup parent = (ViewGroup)(holder.itemView.getParent());
            parent.removeView(holder.itemView);
        } else {
           throw new IllegalArgumentException(
                        "Scrapped or attached views may not be recycled. isScrap:"
                                + holder.isScrap() + " isAttached:"
                                + (holder.itemView.getParent() != null) + exceptionLabel());
                }
            }

猜你喜欢

转载自blog.csdn.net/murphykwu/article/details/79137905