我正面临这场奇怪的崩溃。这是崩溃堆栈。我无法理解为什么它崩溃了,也无法重现此崩溃。它发生在notifyItemChanged(i)
Fatal Exception: java.lang.IllegalStateException: Already in the pool!
at androidx.core.util.Pools$SimplePool.release(Pools.java:117)
at androidx.recyclerview.widget.AdapterHelper.recycleUpdateOp(AdapterHelper.java:743)
at androidx.recyclerview.widget.AdapterHelper.recycleUpdateOpsAndClearList(AdapterHelper.java:750)
at androidx.recyclerview.widget.AdapterHelper.consumePostponedUpdates(AdapterHelper.java:123)
at androidx.recyclerview.widget.AdapterHelper.consumeUpdatesInOnePass(AdapterHelper.java:557)
at androidx.recyclerview.widget.RecyclerView.processAdapterUpdatesAndSetAnimationFlags(RecyclerView.java:3585)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3829)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3639)
at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1877)
at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5044)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1092)
at android.view.Choreographer.doCallbacks(Choreographer.java:893)
at android.view.Choreographer.doFrame(Choreographer.java:809)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1078)
at android.os.Handler.handleCallback(Handler.java:891)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:7539)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)
答案 0 :(得分:2)
当两个不同的线程试图到达您的回收视图实例以对其进行更新时,将引发异常。
让我们澄清一下。假设线程A去更新您的回收视图,然后下一个线程B尝试执行与A相同的操作。结果,抛出异常,说池中已经有A(Already in the pool!
)
经过一些研究以找到解决方案,我找到了这些方法
synchronized(recycleview)
{
}
使用androidx.core.util.Pools.SynchronizedPool<T>
代替androidx.core.util.Pools.SimplePool
两种方法都试图同步访问关键部分,以避免引发异常。
答案 1 :(得分:0)
以下两个选项之一可以解决您的问题:
首先尝试将recyclerView的SupportsChangeAnimations设置为false:
((SimpleItemAnimator) RecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
否则,尝试将ItemAnimator设置为null:
recyclerView.setItemAnimator(null);
错误发生的可能路径:
当recycleview想要对持久项进行动画处理时,它将调用dispatchLayout()方法。 在该方法中,它将检查预测性动画,如果将其设置为false,则它将尝试从AdapterHelper类中使用UpdatesInOnePass()。并且在AdapterHelper类中,它将尝试通过调用consumperPostponedUpdates来推迟更新。因此,如果任何物品已经被回收,那么它 会给您已经存在的池错误。
答案 2 :(得分:0)
您正在更新recyclerView,同时进行计算。 您应该执行以下操作:
if (recyclerView != null) {
recyclerView.post(new Runnable() {
@Override
public void run() {
notifyDataSetChange(); //whatever you use, insert, remove, itemChanged etc...
}
});
}
答案 3 :(得分:0)
我的案例问题的根源是
thisRecycler?.getRecycledViewPool()?.clear()
调用过于频繁以至于没有在该行上执行同步操作
它是作为替代
而引入的notifyItemRangeRemoved(0, previousContentSize)
.
.
notifyItemRangeInserted(0, newRecyclerContent.size - 1)
现在代码稳定使用
notifyItemRangeRemoved(0, previousContentSize)
.
.
notifyDataSetChanged()