Firebase数据过滤时RecyclerView空对象引用异常求助
我每次尝试从Firebase Database过滤数据并添加到RecyclerView时,都会收到空对象引用异常。当使用when(id) { "" -> {...}}逻辑时,所有目标项都能正常添加到RecyclerView,运行正常;但使用when(id) { else -> {...}}逻辑时,就会触发空对象引用异常。
相关代码
fun fetchVideos(id: String?) { if (id == currentFilter) { currentFilter = null return fetchSubs() } currentFilter = id val uid = auth.uid val ref = database.getReference("/content/videos") ref.addListenerForSingleValueEvent(object: ValueEventListener { @SuppressLint("NotifyDataSetChanged") override fun onDataChange(p0: DataSnapshot) { val adapter = GroupAdapter<GroupieViewHolder>() p0.children.forEach { val video = it.getValue(Video::class.java) when(id) { "" -> { if (video != null && video.publisher_uid != uid) { val user = database.getReference("users/$uid/subscriptions/${video.publisher_uid}") user.addListenerForSingleValueEvent(object : ValueEventListener{ override fun onDataChange(p0: DataSnapshot) { val sub = p0.getValue(Subscription::class.java) ?: return if (sub.subscribed == true){ adapter.add(VideoItem(video)) } } override fun onCancelled(error: DatabaseError) { } }) } } else -> { if (video != null && video.publisher_uid == id) { adapter.add(VideoItem(video)) } } } } // New Bottom Sheet adapter.setOnItemClickListener{ item, view -> val videoItem = item as VideoItem selectedVideo = videoItem.video.video_uid HomeFragment.selectedVideo = selectedVideo updateViewCount() addRecentVideo() showVideoPlayer() createValues() } try { sub_recyclerview_videos.adapter = adapter }catch (e: Exception){ Log.d(TAG,"${e.message}") } adapter.notifyDataSetChanged() } override fun onCancelled(p0: DatabaseError) { } }) }
异常信息
尝试调用空对象引用上的虚拟方法 'void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)'
问题分析与解决方法
1. 核心原因
异常直接指向sub_recyclerview_videos为null,说明执行sub_recyclerview_videos.adapter = adapter时,RecyclerView实例尚未完成初始化或无法找到对应视图ID。
两种分支表现不同的原因:""分支嵌套了异步的订阅状态查询,代码执行到设置adapter时,RecyclerView可能已经完成初始化;而else分支是同步添加数据,执行速度更快,此时RecyclerView还未准备好,因此触发空指针。
2. 具体解决步骤
确认RecyclerView初始化时机:
确保sub_recyclerview_videos在视图加载完成后再赋值,比如Fragment中在onViewCreated方法内初始化,Activity中在setContentView之后初始化:// Fragment场景示例 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sub_recyclerview_videos = view.findViewById(R.id.your_recyclerview_id) // 在此之后调用fetchVideos方法 }添加判空保护:
在设置adapter前先检查RecyclerView是否为null,避免直接调用方法:sub_recyclerview_videos?.let { recyclerView -> recyclerView.adapter = adapter adapter.notifyDataSetChanged() } ?: run { Log.d(TAG, "RecyclerView未完成初始化") }统一异步逻辑(可选优化):
""分支用了异步查询,else分支是同步逻辑,执行时机不一致可能引发其他问题。可以将else分支逻辑也改为异步处理,或者用协程等方式等待所有数据准备完成后再更新UI,注意不要阻塞主线程。
3. 额外检查点
- 核对布局文件中RecyclerView的ID与代码中引用的
sub_recyclerview_videos完全一致,避免拼写错误。 - 若使用DataBinding或ViewBinding,确保绑定对象已正确初始化。
内容的提问来源于stack exchange,提问作者Andrey

