findViewById() 可能会产生 NullPointerException

Posted

技术标签:

【中文标题】findViewById() 可能会产生 NullPointerException【英文标题】:findViewById() may produce NullPointerException 【发布时间】:2016-02-13 18:20:09 【问题描述】:

我有很多这样的电话:

(ListView) getView().findViewById(R.id.main_list_view);
(TextView) getView().findViewById(R.id.items_no);
....

androidStudio 告诉我他们可能会生成一个NullPointerException

方法调用getView().findViewById(R.id.main_list_view) 可以 产生java.lang.NullPointerException少... (Ctrl+F1)

此检查分析方法控制和数据流以报告可能 始终为真或假的条件,其值为的表达式 静态证明是恒定的,以及可能导致的情况 违反可空性合同。

变量、方法参数和 标记为@Nullable@NotNull 的返回值被视为可为空 (或分别为非空)并在分析期间用于检查 可空性合同,例如报告可能NullPointerException 错误。

可以使用@Contract 定义更复杂的合约 注释,例如:

@Contract("_, null -> null") — 如果方法的第二个参数为 null,则该方法返回 null @Contract("_, null -> null; _, !null -> !null") — 如果第二个参数为 null,则方法返回 null,否则返回非 null

@Contract("true -> fail") — 一个典型的 assertFalse 方法,如果将 true 传递给它,则会引发异常

检查可以配置为使用自定义@Nullable @NotNull 注解(默认使用 annotations.jar 中的注解)

幸运的是一切正常,但我可以对这段代码进行改进吗?

【问题讨论】:

您想编写无法通过 NPE 的代码? 您使用的是 ViewHolder 模式吗? @takendarkk 不,但我想了解为什么 ide 告诉我它可能会发生 因为如果你给方法一个不存在的 id 会发生什么?它返回空值。一点问题都没有。 我明白了,但是我可以对这段代码进行改进吗? 【参考方案1】:

这是 android.support.v7.app.AppCompatActivity 中的一个已知问题,已在 v24 中修复。

https://code.google.com/p/android/issues/detail?id=203345

android.support.v4.app.FragmentActivity 或 android.app.Activity 不会有任何问题

【讨论】:

【参考方案2】:

应该忽略这个问题;

正如@DanDar3 所写 -> getView() 可以返回 null 并且 AndroidStudio 会突出显示。

但是,如果您真的想让 AndroidStudio 开心 - 当然可以...: 只需断言视图不为空:

View view = getView();
assert view != null;
(ListView) view.findViewById(R.id.main_list_view);
(TextView) view.findViewById(R.id.items_no);

【讨论】:

【参考方案3】:

这是因为 getView() 可能返回 null 并被注释为 @Nullable,请查看源代码及其 JavaDoc - CTRL+单击代码中的 getView() 调用。

/**
 * Get the root view for the fragment's layout (the one returned by @link #onCreateView),
 * if provided.
 * 
 * @return The fragment's root view, or null if it has no layout.
 */
@Nullable
public View getView() 
    return mView;

您可以自己包装代码并检查 null 以使警告消失,或者将光标放在 findViewById() 调用中的任何位置,等待几秒钟让灯泡出现(或按 Alt+Enter)并然后选择建议的解决方案之一。

【讨论】:

以上是关于findViewById() 可能会产生 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

findViewByID在FirestoreRecyclerAdapter中返回null

为啥 findViewById 搜索 RecyclerView 时返回 null?

findViewById返回null

findViewById 返回 null (TextView) [重复]

findViewById() 为对话框中的视图返回 null

findviewbyid 在对话框中返回 null