完整的报错内容是:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
。
问题
最近在写安卓代码的时候遇到了这个问题,看这个报错说明知道是空指针,也就是没有获取到正确的TextView控件而返回了一个空对象,然后你在对相关控件进行操作时就报错了。
但是就算知道了这个bug是什么,也没有能很快解决问题,网上找了一圈发现有以下可能:
- 这个null异常通常是找不到该Layout中的TextView组件,检查layout和初始化组件是否有误(传送门)
- 原因是在你创建的第二个Activity中没有指定选用哪个layout(传送门)
- 原因是你使用的是this.findViewById()来取得GirdView,但事实是这样获取不到该对象。所以正确的做法是:使用布局填充器LayoutInflater的infalte方法(传送门)
大家说的都是没有设置好相应的布局从而没法获取正确的控件,但是我确定我写的设置好了相应的布局,并且也设置了对应的控件,那为什么一运行就报错呢???
- LinearAdapter相关代码
// 设置layout_linear_item布局
public LinearAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
{
return new LinearViewHolder(LayoutInflater.from(mContext).inflate(R.layout.layout_linear_item, viewGroup, false));
}
// 找到TextView控件tv_title
class LinearViewHolder extends RecyclerView.ViewHolder
{
private TextView textView;
public LinearViewHolder(@NonNull View itemView)
{
super(itemView);
textView = itemView.findViewById(R.id.tv_title);
}
}
// 设置内容时报错
public void onBindViewHolder(@NonNull LinearAdapter.LinearViewHolder viewHolder, int i)
{
viewHolder.textView.setText("Hello, world");
}
- layout_linear_item.xml代码
解决(并没有)
后面我想到之前在写layout_list_item布局时好像也用过一个id为tv_title的TextView控件,难道是因为同名原因?于是我把layout_linear_item布局中TextView的id改为了tv_title2,然后再试着运行了下,没想到竟然成功了。但是我是在不同的布局文件中使用相同的id呀!而且也没有混用,以前写过同名id并没有报错,这究竟是为什么呢?
于是我又在网上搜索了一番,发现有人问过类似的问题,但是回答都是类似“当然可以重复id,只要在不同的布局文件中就行了”,比如下面的答案:
看使用的场景以及你查找的方式。
加入2个layout不在一个activity中,那无论怎么使用都没关系,肯定不会乱套。
如果2个layout放到一个activity中了,是会引起混乱的,但这混乱也不是说一定会出现,只是可能。主要是在resume的时候会出现混乱,其他情况是没问题的。
在findviewbyid的时候,记得限定layout,通过layout.findviewbyid的方式查找对应布局下的textview
于是我又把id改回了tv_title,然后运行了下,这回竟然没有错误了!!!再多运行几次也没有报错,简直神奇!已经没有合适的表情包来描述我现在的心情了。
然后我又观察了下,发现在敲代码时Android Studio提示的同名id只会出现一个而且值是一样的,但是好像并没有什么用。
虽然问题并没有真正的解决,但是经过这次教训。我还是觉得以后不使用同名id为好。
当我把代码回退到最初的状态时,问题找到了,我写错了id名,布局文件中的id名是tv_title
而我在LinearAdapter中写成了iv_title
,关键是我之前还真写过id名为iv_title
的控件,真是智障了。
就说到这里吧,要被自己蠢哭了。
The end.
2018-12-21 星期五
深夜发博文的太傅😀
@惶心 又水了一篇😄