RecyclerView gets crashed [IllegalArgumentException] when use notifyItemChanged from Handler using Runnable

╄→гoц情女王★ 提交于 2019-12-03 08:24:16

问题


I'm using RecyclerView as a list to show songs that can be downloaded. Each item has ProgressBar in its View. When the download starts, then I use a Handler to notify each item to update the ProgressBar to show the song download progress.

Q1. Is this is a correct way to do it or Is there any other way to do it more appropriately.

Q2. RecyclerView gets crashed when we use adapter.notifyItemChanged(position); to update the content of single item. It is called from a Handler using Runnable. But, the log don't show any traces for my code. Why?

Below is the log for this issue:

05-06 19:09:45.804: E/AndroidRuntime(32115): FATAL EXCEPTION: main
05-06 19:09:45.804: E/AndroidRuntime(32115): java.lang.IllegalArgumentException: Tmp detached view should be removed from RecyclerView before it can be recycled: ViewHolder{41b7bec0 position=6 id=-1, oldPos=-1, pLpos:-1 update changed tmpDetachedundefined adapter position no parent}
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:3861)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.support.v7.widget.RecyclerView.removeAnimatingView(RecyclerView.java:779)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.support.v7.widget.RecyclerView.access$5300(RecyclerView.java:127)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.support.v7.widget.RecyclerView$ItemAnimatorRestoreListener.onAddFinished(RecyclerView.java:8228)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.support.v7.widget.RecyclerView$ItemAnimator.dispatchAddFinished(RecyclerView.java:8573)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.support.v7.widget.DefaultItemAnimator$5.onAnimationEnd(DefaultItemAnimator.java:239)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.support.v4.view.ViewPropertyAnimatorCompatJB$1.onAnimationEnd(ViewPropertyAnimatorCompatJB.java:47)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.view.ViewPropertyAnimator$AnimatorEventListener.onAnimationEnd(ViewPropertyAnimator.java:973)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1012)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.animation.ValueAnimator.access$400(ValueAnimator.java:51)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:623)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:639)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.view.Choreographer.doCallbacks(Choreographer.java:579)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.view.Choreographer.doFrame(Choreographer.java:547)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.os.Handler.handleCallback(Handler.java:725)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.os.Handler.dispatchMessage(Handler.java:92)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.os.Looper.loop(Looper.java:153)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at android.app.ActivityThread.main(ActivityThread.java:5297)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at java.lang.reflect.Method.invokeNative(Native Method)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at java.lang.reflect.Method.invoke(Method.java:511)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
05-06 19:09:45.804: E/AndroidRuntime(32115):    at dalvik.system.NativeStart.main(Native Method)

I searched to find the solution for this but couldn't find any appropriate answer.


回答1:


We also had this issue on our application, and after a really long debugging session we found out that it was caused by adapter.setHasStableIds(true)

We removed the offending line and the issue is finally gone.

Hope it helps.




回答2:


i had the same issue,i could handle it by disabling the animator of recyclerview:

recyclerView.itemAnimator = null




回答3:


adapter.notifyItemChanged(position);must be called from the main thread

instead of your Handler use the Handler with mainLooper

    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            //HERE
        }
    });



回答4:


I faced the same problem but turned out the reason was calling scrollToPosition. The solution that worked for me after many attempts was to call notifyDataSetChanged before scrolling (all from the UI thread of course). Maybe it will help someone.




回答5:


There are several workarounds to the problem:

  1. Call to notifyDataSetChanged() instead notifyItemChanged(). It is the less efficient way to solve it.

  2. As pointed by Henrique de Sousa, remove the line adapter.setHasStableIds(true) prevents the problem.

But the real solution (as commented by southerton), if the adapter is stable, is to implement and correctly getItemId(), honouring the "hasStableIds" value set.




回答6:


Since this is the first post to come up I'll post another solution to the problem which helped in my specific case: I was hiding the parentview containing the recyclerview using

parentView.setVisibility(View.GONE);

recyclerview does not like that, apparently if you want to hide a view which contains a recyclerview, you can only use View.INVISIBLE.




回答7:


For me the issue was resolved after I removed animateLayoutChanges=“true” from the parent ViewGroup of the recyclerview.



来源:https://stackoverflow.com/questions/30078834/recyclerview-gets-crashed-illegalargumentexception-when-use-notifyitemchanged

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!