在AndroidStudio 3.0.1中,DialogFragment getActivity()“可能为空”lint警告

时间:2017-12-27 15:50:51

标签: java android lint

我能找到的最近的问题是Android Studio 3.0 lint warnings for references to activity,但它无济于事。

使用AndroidStudio 3.0.1,我有一个DialogFragment,我通常会这样做:

    @Override
    @NonNull
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        ...

我有一条皮棉警告呻吟着Argument 'getActivity()' might be null

我理解为什么 getActivity()可能为null,我理解lint检查如何知道这一点(来自@Nullable注释)。

我的问题是:getActivity()可能是空的,这一切都非常好,但实际上我应该如何优雅和整洁地处理这个问题? onCreateDialog 必须返回Dialog(因为超类'@Nullable注释)所以我必须拥有Activity上下文才能创建它。

如果onCreateDialog没有附加到某个活动,我可以假设永远不会调用DialogFragment,但仍然 - 我如何处理不整齐的lint警告?

4 个答案:

答案 0 :(得分:24)

@Niklas的回答解释了为什么你现在得到这个警告。我想分享一下你应该做些什么的想法。

首先,所有这些增加的可空性确实暴露了这些年来出现的旧设计缺陷 - 这种方法总是可以返回null(例如片段分离)。

我更喜欢如果他们将返回值注释为@NonNull并在内部抛出异常,如果在Activity实际为null时调用此方法,但我知道它会破坏向后兼容性并且因此非常危险(尽管我很难看看为什么有人会在Activity实际上为null时调用此方法。

那么,我们应该怎么做呢?

首先,由于功能根本没有改变,如果有问题的代码已经有效,那么就按照@CommonsWare的建议进行操作 - 压制警告或忽略它。

你也可以将每个调用包装成null检查,例如异常。

然而,我要做的是将此方法放在我的BaseDialog中(由所有其他对话框扩展):

protected FragmentActivity getActivityNonNull() {
    if (super.getActivity() != null) {
        return super.getActivity();
    } else {
        throw new RuntimeException("null returned from getActivity()");
    }
}

请注意,所有这些选项都有效地表明您并不真正期望返回null,如果发生这种情况,应用程序崩溃就可以了。这就是为什么我说我宁愿在支持库代码中使用它。

修改

添加了一种新方法来支持片段 - requireActivity()。此方法相当于上面描述的getActivityNonNull()(如果未附加到Activity,则会抛出IllegalStateException

使用此方法代替getActivity(),您应该做得很好。

答案 1 :(得分:2)

这是 - Android Studio 3.0 lint warnings for references to activity的副本。

tldr; getActivity()使用支持lib 27.0.0获得注释@Nullable,静态分析工具现在选择它。

答案 2 :(得分:2)

版本27.1.0发行版中添加了以下方法:片段现在具有requireContext()requireActivity()requireHost()requireFragmentManager()方法,这些方法返回以下对象的NonNull对象:等效的get方法或抛出IllegalStateException。

答案 3 :(得分:0)

对于那些想要查看requireActivity()方法的源代码的人:

 @NonNull 
 public final FragmentActivity requireActivity() { 
     FragmentActivity activity = this.getActivity();
     if (activity == null) { 
         throw new IllegalStateException(
             "Fragment " + this + " not attached to an activity."
         );
     } else {
         return activity; 
     }
 }