android - Kotlin fragment NullPointerException

标签 android kotlin nullpointerexception

在 Kotlin 中编写程序并使用 fragment 显示用户列表,其中从 Firebase 填充 RecyclerView 但有时会出现 NullPointerException,发布日志和代码

日志:

java.lang.NullPointerException
        at com.fb.hc.fragments.UsersFragment$retrieveAllUser$1.onDataChange(UsersFragment.kt:108)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.3.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.3.0:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.3.0:55)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7807)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)

代码:

class UsersFragment : Fragment() {

    private var userAdapter: UsersAdapter? = null
    private var mUsers: List<Users>? = null
    ....

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view: View = inflater.inflate(R.layout.fragment_users, container, false)

        mUsers = ArrayList()

        retrieveAllUser()

        return view
    }

    private fun retrieveAllUser() {

        val firebaseUserID = FirebaseAuth.getInstance().currentUser!!.uid
        val refUser = FirebaseDatabase.getInstance().reference.child("Users")

        refUser.addValueEventListener(object : ValueEventListener{
            override fun onDataChange(p0: DataSnapshot)
            {
                (mUsers as ArrayList).clear()

                if (topicCompleteView.text.toString() == "") {

                    for (snapshot in p0.children)
                    {
                        val user: Users? = snapshot.getValue(Users::class.java)
                        if (!(user?.getUID()).equals(firebaseUserID) && user != null) {
                            (mUsers as ArrayList<Users>).add(user)
                        }
                    }

                    if (mUsers.isNullOrEmpty()) {


                    } else {

                        // error line
                        userAdapter = UsersAdapter(context!!, mUsers as ArrayList<Users>, false)
                        recyclerView.adapter = userAdapter

                    }

                 }
            }

最佳答案

您直接在 fragment 中执行异步 I/O。然后,当该工作完成时,您将尝试更新 fragment 的 UI。

问题是有时您的 fragment 会在该工作完成之前被销毁(例如,用户按下返回按钮)。在那种情况下,context 将是 null 并且 context!! 将是......不好的。

战术修复是只有在有上下文时才更新 UI:

activity?.let {
    userAdapter = UsersAdapter(it, mUsers as ArrayList<Users>, false)
    recyclerView.adapter = userAdapter
}

较好的解决方法是将此 I/O 完全从 fragment 中移除。如果用户触发配置更改(旋转屏幕、切换黑暗模式等),您的新 fragment 将不会从原始 fragment 获取 I/O 结果。最好将此 I/O 移动到您的 fragment 使用的 ViewModel 中,您可以在其中通过 LiveData 或类似机制提供这些结果。您的 fragment 将观察 LiveData 并应用结果。这不仅修复了崩溃,而且还更好地处理配置更改。

关于android - Kotlin fragment NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62865987/

相关文章:

java - :app:transformClassesWithJarMergingForDebug失败(未使用jsonpath)

java - 运行时 NullPointerException

Android 模拟器未与我的 React Native 应用程序一起运行

java - 从 Android 项目中的包中检索类列表

kotlin - 将 Kotlin 与生成的 Java 类集成

android - 单击列表项时如何从一个 fragment 切换到另一个 fragment ?

android - 不允许直接解析配置 'debugCompile'

java - 将数据存储到对象数组元素中返回 NullPointerException

java - 空指针异常构造函数

java - ListView 中的微调器似乎出现在 ListView 之外