即使在 onAttach() 中设置,Fragment 中的活动也为空

Posted

技术标签:

【中文标题】即使在 onAttach() 中设置,Fragment 中的活动也为空【英文标题】:Null activity in Fragment even when setting in onAttach() 【发布时间】:2018-07-12 02:20:44 【问题描述】:

我的代码如下所示:

(注意:请注意底部的行,我收到 NullPointerException 的报告。此外,这篇文章已经过大量编辑,但我相信所有相关代码都包括在内)

public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener 

     public SettingsActivity activity;

     @Override
     public void onAttach(Context context) 
         super.onAttach(context);

         if (context instanceof Activity) 
             activity = (SettingsActivity) context;
         
     

     @Override
     public void onActivityCreated(@Nullable Bundle savedInstanceState) 
         super.onActivityCreated(savedInstanceState);

         addPreferencesFromResource(R.xml.preferences);

         final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
     


     @Override
     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String prefKey) 

         // The line below gets many NullPointerException reports
         SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity);
     
 

我认为通过在onAttach() 中设置activity 变量几乎可以确保它不为空。 (而不是使用getActivity()

我拥有的 getActivity() 实例有 0 个报告曾经为空。看来我只需要改用它。 但我想知道活动是如何为空的,并且正在将其更改为 getActivity() 的方式吗?

FWIW,我没有在这个类中使用onDetach()

只是一个猜测:在我看来 onAttach() 可以在 onSharedPreferenceChanged() 被调用之前被调用,所以到那时 activity 可能会变为空?

activity 变量总是有可能不是 null 并且它是该行中的其他内容,但这对我来说似乎是最明显的?

【问题讨论】:

当SharedPreferences对象作为参数传递时,为什么还需要创建它? @Submersed 假设这些对象包含相同的数据,我想这是一个疏忽。不过,我仍然想知道空 activity 的情况是怎么回事。 【参考方案1】:

你应该使用

@Override
public void onAttach (Activity activity) 
    super.onAttach(activity)

改为

@Override
public void onAttach (Context context) 
    super.onAttach(context)
 

虽然第一个功能已被弃用,但它仍然可以正常工作。试试看吧。

【讨论】:

不确定我是否喜欢返回已弃用的内容进行修复(除非新内容有已知的错误,而这里确实不是这种情况)

以上是关于即使在 onAttach() 中设置,Fragment 中的活动也为空的主要内容,如果未能解决你的问题,请参考以下文章

即使在清单中设置了权限,权限异常[重复]

即使在 Laravel eloquent 中设置后,表名也不会改变?

想要那个 .scroll 动画,即使数据源没有在 UIPageViewController 中设置

即使在钥匙串安全之后,仍然可以在代码中设置凭据

为啥 HttpClient 不保存基地址,即使它在 Startup 中设置

即使在 webpack.DefinePlugin 中设置了环境变量,也没有在电子中定义