RecyclerView状态异常Cannot call this method while RecyclerView is computing a layout or scrolling

错误堆栈

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView.............layout:androidx.recyclerview.widget.GridLayoutManager@ca48e86, context:..........@a799d74
	at androidx.recyclerview.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2880)
	at androidx.recyclerview.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:5281)
	at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11997)
	at androidx.recyclerview.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:7070)
......
at android.os.Handler.handleCallback(Handler.java:938)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:240)
	at android.app.ActivityThread.main(ActivityThread.java:8000)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:603)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

报错代码

在RecyclerView中抛异常的地方
在这里插入图片描述在RecyclerView进行数据更新的时候,会进行判断当前RecyclerView是否正在布局遍历或者滚动,如果是就抛出异常
在这里插入图片描述
在这里插入图片描述

isComputingLayout方法

在这里插入图片描述这个方法用来判断RecyclerView当前是否在计算布局,这段注释的意思是:

返回RecyclerView当前是否正在计算布局。
如果此方法返回true,则意味着RecyclerView处于锁定状态
尝试更新适配器内容将导致异常,因为适配器内容
当RecyclerView尝试计算布局时,无法更改。
您的代码不太可能在这种状态下运行
当发生布局遍历或RecyclerView开始滚动时,由框架调用
响应系统事件(触摸、可访问性等)。
如果您有一些自定义逻辑来更改中的适配器内容,则可能会发生这种情况
对视图回调(例如焦点更改回调)的响应
布局计算。在这些情况下,您应该使用Handler或类似的机制。
返回true,如果RecyclerView当前正在计算布局,false否则

注释里面说,在这种情况下应该使用Handler来处理

mLayoutOrScrollCounter这个变量注释
在这里插入图片描述意思是

在dispatchLayout和/或滚动期间,此变量递增。
在这些期间不应调用某些方法(例如适配器数据更改)。
这样做会导致很难找到bug,所以我们最好检查一下并抛出异常。
参见#assertInLayoutOrScroll(字符串)
参见#assertNotInLayoutOrScroll(字符串)

所以这个变量大于0就表示RecyclerView当前正在布局或滚动。

解决办法

综上所诉,当出现这个异常的时候,应当把数据更新的代码放在handler中。

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

猜你喜欢

转载自blog.csdn.net/qq_34681580/article/details/127205950