【问题标题】:RecyclerView crashes with IndexOutOfBoundException on often updatesRecyclerView 在经常更新时因 IndexOutOfBoundException 而崩溃
【发布时间】:2019-08-27 10:46:19
【问题描述】:

我必须经常向适配器提交 RecyclerView 更新(有时 1 秒内 2-3 次更新)。我正在使用notifyDataSetChanged()的方法。

adapter.items = listOf(NewItem())
adapter.notifyDataSetChanged()

这有时会导致应用在后台崩溃并显示 IndexOutOfBoundException(下面的堆栈跟踪)的问题。

java.lang.IndexOutOfBoundsException: 
  at java.util.ArrayList.get (ArrayList.java:437)
  at android.view.View.draw (View.java:20366)
  at android.view.View.buildDrawingCacheImpl (View.java:19637)
  at android.view.View.buildDrawingCache (View.java:19497)
  at android.view.View.draw (View.java:20086)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw (ConstraintLayout.java:2023)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at androidx.recyclerview.widget.RecyclerView.drawChild (RecyclerView.java:4820)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.draw (View.java:20369)
  at androidx.recyclerview.widget.RecyclerView.draw (RecyclerView.java:4219)
  at android.view.View.updateDisplayListIfDirty (View.java:19241)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw (ConstraintLayout.java:2023)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.updateDisplayListIfDirty (View.java:19232)
  at android.view.View.draw (View.java:20094)
  at android.view.ViewGroup.drawChild (ViewGroup.java:4337)
  at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4116)
  at android.view.View.draw (View.java:20369)
  at com.android.internal.policy.DecorView.draw (DecorView.java:781)
  at android.view.View.updateDisplayListIfDirty (View.java:19241)
  at android.view.ThreadedRenderer.updateViewTreeDisplayList (ThreadedRenderer.java:690)
  at android.view.ThreadedRenderer.updateRootDisplayList (ThreadedRenderer.java:696)
  at android.view.ThreadedRenderer.draw (ThreadedRenderer.java:805)
  at android.view.ViewRootImpl.draw (ViewRootImpl.java:3526)
  at android.view.ViewRootImpl.performDraw (ViewRootImpl.java:3316)
  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2685)
  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1637)
  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:7797)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:1172)
  at android.view.Choreographer.doCallbacks (Choreographer.java:984)
  at android.view.Choreographer.doFrame (Choreographer.java:809)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:1158)
  at android.os.Handler.handleCallback (Handler.java:873)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:193)
  at android.app.ActivityThread.main (ActivityThread.java:6898)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:537)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:858)

我尝试了使用和不使用 DiffUtils,结果是一样的。

当我更新适配器(应用新项目并在几秒钟内调用一次 notifyDataSetChanged() 时,一切都很好,没有问题。如果 1 秒内有多个更新,就会发生这种情况。

【问题讨论】:

  • 您能否分享更多来自您的适配器的代码以及调用 adapter.notifyDataSetChanged() 的位置?

标签: android android-recyclerview


【解决方案1】:

在 Java 中,当您尝试访问无效索引时会发生 IndexOutofbounds 异常。

所以最好的方法是用空列表初始化你的适配器。

private var list = ArrayList<String>
private lateinit var adapter:<YourAdapterClass>

onCreate(){
**// Initialise your adapter with empty list**
adapter = YourAdapter(list)

// Your Operation: for eg, getting data from api:
list.add("<Your element>")

// Once updates are done.

**adapter.notifyDataSetChange()**

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2012-03-31
    • 2021-12-31
    • 2014-04-10
    • 1970-01-01
    相关资源
    最近更新 更多