You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView点击触发NullPointerException崩溃排查求助

RecyclerView空指针崩溃排查求助

崩溃基本信息

  • 涉及设备:
    • Infinix-X688B(Android 11,SDK 30)
    • samsung a3core(Android 13,SDK 33)
    • TECNO-BG6(Android 13,SDK 33)
    • POCO aresin(Android 13,SDK 33)
  • 崩溃频率:约每三天或更久出现一次,应用日活跃用户超1000人
  • 崩溃报错:java.lang.NullPointerException
  • 怀疑关联代码:
public void onBindViewHolder(@NonNull RowViewHolder holder, int position) {
       ......
              holder.itemView.setOnClickListener(v -> {
                int old_postion =-1;
                old_postion = position;
                if(old_postion == position){
                    int colorBlue = ContextCompat.getColor(holder.itemView.getContext(), R.color.black);
                    v.setBackgroundColor(colorBlue);
                    notifyItemChanged(old_postion);
                }
            });
    }
  • 崩溃堆栈:
Exception java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()' on a null object reference
  at androidx.recyclerview.widget.RecyclerView$LayoutManager.getPosition (RecyclerView.java)
  at androidx.recyclerview.widget.LinearLayoutManager.findReferenceChild (LinearLayoutManager.java)
  at androidx.recyclerview.widget.LinearLayoutManager.findFirstReferenceChild (LinearLayoutManager.java)
  at androidx.recyclerview.widget.LinearLayoutManager.findReferenceChildClosestToStart (LinearLayoutManager.java:7)
  at androidx.recyclerview.widget.LinearLayoutManager.updateAnchorFromChildren (LinearLayoutManager.java:7)
  at androidx.recyclerview.widget.LinearLayoutManager.updateAnchorInfoForLayout (LinearLayoutManager.java:7)
  at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren (LinearLayoutManager.java:7)
  at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2 (RecyclerView.java)
  at androidx.recyclerview.widget.RecyclerView.onMeasure (RecyclerView.java:2)
  at android.view.View.measure (View.java:26488)
  at android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:7109)
  at android.widget.LinearLayout.measureChildBeforeLayout (LinearLayout.java:1552)
  at android.widget.LinearLayout.measureVertical (LinearLayout.java:842)
  at android.widget.LinearLayout.onMeasure (LinearLayout.java:721)
  at android.view.View.measure (View.java:26488)
  at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure (ConstraintLayout.java:23)
  at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.measure (ConstraintWidgetContainer.java:7)
  at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.layout (ConstraintWidgetContainer.java:43)
  at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solveLinearSystem (BasicMeasure.java:8)
  at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solverMeasure (BasicMeasure.java:62)
  at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.measure (ConstraintWidgetContainer.java:62)
  at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem (ConstraintLayout.java:62)
  at androidx.constraintlayout.widget.ConstraintLayout.onMeasure (ConstraintLayout.java:62)
  at android.view.View.measure (View.java:26488)
  at android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:7109)
  at android.widget.FrameLayout.onMeasure (FrameLayout.java:194)
  at androidx.appcompat.widget.ContentFrameLayout.onMeasure (ContentFrameLayout.java)
  at android.view.View.measure (View.java:26488)
  at android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:7109)
  at android.widget.LinearLayout.measureChildBeforeLayout (LinearLayout.java:1552)
  at android.widget.LinearLayout.measureVertical (LinearLayout.java:842)
  at android.widget.LinearLayout.onMeasure (LinearLayout.java:721)
  at android.view.View.measure (View.java:26488)
  at android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:7109)
  at android.widget.FrameLayout.onMeasure (FrameLayout.java:194)
  at android.view.View.measure (View.java:26488)
  at android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:7109)
  at android.widget.LinearLayout.measureChildBeforeLayout (LinearLayout.java:1552)
  at android.widget.LinearLayout.measureVertical (LinearLayout.java:842)
  at android.widget.LinearLayout.onMeasure (LinearLayout.java:721)
  at android.view.View.measure (View.java:26488)
  at android.view.ViewGroup.measureChildWithMargins (ViewGroup.java:7109)
  at android.widget.FrameLayout.onMeasure (FrameLayout.java:194)
  at com.android.internal.policy.DecorView.onMeasure (DecorView.java:762)
  at android.view.View.measure (View.java:26488)
  at android.view.ViewRootImpl.performMeasure (ViewRootImpl.java:4079)
  at android.view.ViewRootImpl.measureHierarchy (ViewRootImpl.java:2794)
  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:3059)
  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:2510)
  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:9266)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:1234)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:1242)
  at android.view.Choreographer.doCallbacks (Choreographer.java:902)
  at android.view.Choreographer.doFrame (Choreographer.java:835)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:1217)
  at android.os.Handler.handleCallback (Handler.java:942)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loopOnce (Looper.java:201)
  at android.os.Looper.loop (Looper.java:288)
  at android.app.ActivityThread.main (ActivityThread.java:8194)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:703)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:911)

排查情况

已检查RecyclerView Adapter代码,未发现明显异常,但无法定位崩溃具体原因,请求协助排查。


排查思路

  1. 避免重复设置点击事件:每次onBindViewHolder调用都会给itemView添加新的点击监听,可能导致多次触发notifyItemChanged,引发布局异常。建议在ViewHolder构造方法中设置点击事件,通过getAdapterPosition()获取当前位置(该方法能实时反映视图对应的数据集位置,比onBindViewHolder的position更可靠)。

修改示例:

class RowViewHolder extends RecyclerView.ViewHolder {
    public RowViewHolder(@NonNull View itemView) {
        super(itemView);
        itemView.setOnClickListener(v -> {
            int currentPosition = getAdapterPosition();
            if (currentPosition != RecyclerView.NO_POSITION) {
                int colorBlack = ContextCompat.getColor(itemView.getContext(), R.color.black);
                v.setBackgroundColor(colorBlack);
                notifyItemChanged(currentPosition);
            }
        });
    }
}
  1. 避免布局阶段触发UI更新:当前点击事件中直接调用notifyItemChanged会触发RecyclerView重新布局,若此时正处于测量/布局流程(如堆栈显示的RecyclerView.onMeasure),可能导致视图引用为空。可通过post延迟执行更新:
itemView.post(() -> {
    int currentPosition = getAdapterPosition();
    if (currentPosition != RecyclerView.NO_POSITION) {
        notifyItemChanged(currentPosition);
    }
});
  1. 确保线程安全:所有数据集修改和notifyXXX方法调用必须在主线程执行,后台线程操作可能导致布局时数据不一致,引发空指针。

  2. 升级RecyclerView版本:该空指针可能是旧版本RecyclerView的已知bug,尝试升级到最新的androidx.recyclerview:recyclerview依赖,修复潜在的布局逻辑问题。


内容的提问来源于stack exchange,提问作者fekhreddine bouziane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 12:19:50