我能找到的最近的问题是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警告?
答案 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;
}
}