Android静态上下文调用非静态show()方法致FragmentActivity崩溃
问题根因
你遇到的non-static method show(FragmentManager,String) cannot be referenced from a static context报错,核心原因是调用show()方法的主体写错了:show()是BottomSheetDialogFragment继承自DialogFragment的实例方法,只能通过Fragment类的实例对象调用,不能直接通过类名调用。你在AdminHomeFragment的列表点击逻辑里,直接写AdminComplaintDetailsFragment.show(...)就是把实例方法当成静态方法调用了,直接触发报错。
除此之外你的现有代码还存在两个会导致后续崩溃的隐患:
- 刚通过
new创建的Fragment未经过挂载流程,调用getTag()返回值为null,就算修正了调用主体,传入null作为tag也可能引发异常 - 你通过自定义带参构造函数给Fragment传递
Complaint对象不符合Android Fragment开发规范,当应用内存不足被系统回收重建时,Fragment只会调用无参构造,你传入的对象会丢失,触发空指针崩溃。
修复步骤
1. 修正show方法的错误调用
找到AdminHomeFragment.java里列表项点击的代码块,把错误的调用逻辑替换为如下代码:
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Complaint present = (Complaint) arrayList.get(position); AdminComplaintDetailsFragment admincomplaintDetailsFragment= new AdminComplaintDetailsFragment(present); // 用创建好的Fragment实例调用show方法,传入自定义非空tag admincomplaintDetailsFragment.show(requireActivity().getSupportFragmentManager(), "admin_complaint_detail"); } });
这里用requireActivity()替代原来的(FragmentActivity)getContext()写法,可以避免context为空时的类型转换崩溃,是AndroidX Fragment提供的标准API。
2. (强烈建议)修复Fragment传参的不规范写法
为了避免内存重建时的参数丢失问题,请按如下方式修改AdminComplaintDetailsFragment.java:
- 确保你的
Complaint类实现了Serializable接口(如果追求性能可以实现Parcelable接口) - 移除自定义的带参构造函数
public AdminComplaintDetailsFragment(Complaint present),仅保留类中已有的无参构造(这是系统重建Fragment必须的) - 新增静态工厂方法创建Fragment实例,通过
Bundle传递参数:
public static AdminComplaintDetailsFragment newInstance(Complaint present) { AdminComplaintDetailsFragment fragment = new AdminComplaintDetailsFragment(); Bundle args = new Bundle(); // 如果Complaint实现的是Parcelable,这里换成putParcelable args.putSerializable("extra_complaint", present); fragment.setArguments(args); return fragment; }
- 在
onCreate生命周期方法中读取传入的参数:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { present = (Complaint) getArguments().getSerializable("extra_complaint"); // 原模板生成的mParam1、mParam2读取逻辑可以直接删除,没有实际作用 } }
- 回到
AdminHomeFragment的点击逻辑,把创建Fragment的代码替换为工厂方法调用:
// 替换原来的new AdminComplaintDetailsFragment(present)写法 AdminComplaintDetailsFragment admincomplaintDetailsFragment = AdminComplaintDetailsFragment.newInstance(present); admincomplaintDetailsFragment.show(requireActivity().getSupportFragmentManager(), "admin_complaint_detail");
修改完成后重新编译运行,静态调用报错和后续的潜在崩溃问题都会被解决。
内容的提问来源于stack exchange,提问作者out_of_username
相关产品推荐
相关产品推荐

