使用recyleroption报Context空指针 调用getPackageName()错误关联Fragment
异常问题说明
- 报错信息:
Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference - 复现特征:
- 使用普通RecyclerView适配器无该异常
- 改用recyleroption时触发异常
- 问题与Fragment使用场景强相关
- 异常触发位置:适配器
onBindViewHolder方法中设置的itemView点击事件内的Intent创建、启动逻辑
异常关联代码
@Override protected void onBindViewHolder(@NonNull myViewHolder holder, int i, @NonNull Itemmodel itemmodel) { String quantity=itemmodel.getPquantityet(); String id=itemmodel.getProductid(); String priceavailable=itemmodel.getPriceavailable(); holder.titletv.setText(itemmodel.getProductname()); holder.descriptiontv.setText(itemmodel.getPdescription()); holder.quantitytv.setText(quantity); holder.pricetv.setText(itemmodel.getPprice()); /* if(priceavailable.equals("true")) { holder.pricetv.setText(modelitem.getPprice()); }else { holder.pricetv.setVisibility(View.GONE); }*/ if(Integer.parseInt(quantity)<=5){ holder.dangerpic.setVisibility(View.VISIBLE); }else { holder.dangerpic.setVisibility(View.GONE); } holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Error is on Intent Intent intent=new Intent(context,BilActivity.class); intent.putExtra("id",id); context.startActivity(intent); } }); }
问题根因
异常直接来源是代码中使用的context变量为null。创建Intent、调用startActivity()时,系统需要通过Context获取应用包名,此时访问空Context就会抛出该异常。
结合复现特征可推导:你在Fragment中使用该适配器时,传入适配器的Context来源于Fragment自身或Fragment的getContext()方法。当Fragment进入onDestroyView、onDetach状态,或是处于回退栈未完全恢复的状态时,Fragment关联的Context会被系统置空,后续item点击事件触发时,就会访问到已经失效的空Context。普通适配器实现时你大概率传入了稳定的Activity Context,因此不会触发该问题。
修复方案
- 点击事件内直接使用itemView的上下文,不依赖适配器持有全局Context:
holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 直接获取当前itemView绑定的有效上下文,避免空引用 Intent intent = new Intent(v.getContext(), BilActivity.class); intent.putExtra("id", id); v.getContext().startActivity(intent); } });
- 如果确实需要在适配器中持有Context,必须在Fragment的
onAttach()阶段获取稳定的Activity Context实例传入,禁止直接传Fragment对象作为Context;同时在Fragment的onDestroyView()阶段调用适配器的清理方法,移除所有事件回调,避免访问失效引用。 - 适配器初始化时增加Context非空校验,从源头规避空引用传入的问题。
内容的提问来源于stack exchange,提问作者jameel khan
相关产品推荐
相关产品推荐

