进入设置Activity旋转设备出现Could not find fragment constructor错误如何解决
问题原因
- 屏幕旋转属于Android系统配置变更,此时系统会自动销毁并重建Activity与关联的Fragment,重建Fragment时系统会通过反射调用Fragment的无参构造方法。你当前的
SettingsFragment只定义了带SettingsActivity参数的构造,没有提供无参构造,因此触发"could not find fragment constructor"报错。 - 通过构造方法传递Activity实例的写法不符合Fragment的最佳实践,就算强行添加无参构造,系统重建Fragment时你之前传入的Activity实例也会失效,后续调用时会触发空指针异常。
修复方案
第一步:修改SettingsFragment代码
移除自定义带参构造,通过onAttach生命周期方法获取挂载的Activity,同时必须添加无参构造供系统重建调用:
public static class SettingsFragment extends PreferenceFragmentCompat { private SettingsActivity mActivity; // 必须添加无参构造,供系统重建Fragment时反射调用 public SettingsFragment() {} @Override public void onAttach(@NonNull Context context) { super.onAttach(context); if (context instanceof SettingsActivity) { mActivity = (SettingsActivity) context; } } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.root_preferences, rootKey); ListPreference listPreference = findPreference("jojojojo"); if (listPreference != null) { listPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (mActivity != null) { mActivity.setResult(1); } return true; } }); } SwitchPreferenceCompat switchPreferenceCompat = findPreference("lalalala"); if (switchPreferenceCompat != null) { switchPreferenceCompat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (mActivity == null) { return true; } if ((boolean)newValue) { mActivity.mostrarMensaje(getString(R.string.toastFrasesOn)); mActivity.setResult(2); } else { mActivity.setResult(3); } return true; } }); } } @Override public void onDetach() { super.onDetach(); // 置空引用避免内存泄漏 mActivity = null; } }
第二步:修改Activity中Fragment初始化逻辑
把原来传入Activity实例的构造调用改为调用无参构造即可:
if (savedInstanceState == null) { getSupportFragmentManager() .beginTransaction() .replace(R.id.settings, new SettingsFragment()) .commit(); }
内容的提问来源于stack exchange,提问作者Mike087
相关产品推荐
相关产品推荐

