Android自定义Parcelable类通过Intent传递后接收为空报NPE如何解决
问题排查与解决步骤
核心原因定位
mTopic为空只有两种可能:传递时传入的对象本身为null,或接收时解析失败,结合你的代码,前者概率远高于后者,按以下顺序排查即可:
排查步骤
第一步:检查Firebase拉取的数据是否存在空对象
你在forum页的onDataChange中直接将dss.getValue(topic.class)的结果加入列表,没有做判空:
当Firebase的forum_topics节点下存在不符合topic类结构的数据、空节点、或缺少必要字段时,getValue()会直接返回null,这些null对象会被加入列表,点击对应项时就会传递空对象。
修复代码:
for (DataSnapshot dss: snapshot.getChildren()){ topic top = dss.getValue(topic.class); // 新增判空,仅将有效对象加入列表 if (top != null) { // 补充:如果你的topic的id字段存的是Firebase节点key,这里需要手动赋值 top.setId(dss.getKey()); topicList.add(top); } }
同时可以加日志打印拉取到的每个对象,确认是否存在null值。
第二步:检查列表适配器的回调逻辑
确认forumAdapter的点击回调中,拿到的topic对象是否有效:
比如在适配器的点击事件中,先校验获取到的列表项是否为空,再触发回调:
// 适配器onBindViewHolder中的点击逻辑示例 itemView.setOnClickListener(v -> { int position = getAdapterPosition(); // 校验位置有效性、对象有效性 if (position != RecyclerView.NO_POSITION && topicList.get(position) != null) { listener.onTopicClick(topicList.get(position)); } });
同时可以在跳转前加日志,确认传递的mTopic是否为空:
myadapter = new forumAdapter(forum.this, topicList, mTopic -> { Log.d("传递校验", "待传递的topic对象:" + mTopic); if (mTopic == null) { Toast.makeText(forum.this, "该话题数据异常,无法打开", Toast.LENGTH_SHORT).show(); return; } Intent intent = new Intent(forum.this, topic_chat.class); intent.putExtra("topic",mTopic); startActivity(intent); });
第三步:接收侧加空值保护
无论传递侧是否有问题,接收侧都要加空值判断,避免崩溃:
mTopic = getIntent().getParcelableExtra("topic"); if (mTopic == null) { Toast.makeText(topic_chat.this, "话题数据加载失败,请返回重试", Toast.LENGTH_SHORT).show(); finish(); // 直接关闭页面,避免后续空指针 return; } // 后续正常逻辑写在判空之后
额外校验点
确认传递和接收的Extra键完全一致,没有大小写错误、多余空格,你的代码中键都是"topic",这点暂时没问题;同时你的topic类Parcelable实现是正确的,读写字段顺序一致,CREATOR写法符合要求,不会因为序列化本身导致空对象。
内容的提问来源于stack exchange,提问作者Zabava Mihai
相关产品推荐
相关产品推荐

