You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击setOnClickListener绑定的保存按钮后应用崩溃的原因排查

问题分析:Firebase数据上传后应用崩溃

我通过Firebase实现表单提交+封面图上传功能,填写表单并选择图片后,点击绑定了setOnClickListener的「保存」按钮,按钮负责将所有信息和图片上传至Firebase,之后返回主页面。但主页面显示前应用崩溃,抛出如下错误:

2022-08-16 20:49:53.847 21445-21445/com.example.gesit E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.gesit, PID: 21445
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.material.button.MaterialButton.setEnabled(boolean)' on a null object reference
        at com.example.gesit.TambahProduk.saveProductInformation$lambda-6(TambahProduk.kt:313)
        at com.example.gesit.TambahProduk.$r8$lambda$WSqVgd-3d_M5F9vVqHMPnqwiv5o(Unknown Source:0)
        at com.example.gesit.TambahProduk$$ExternalSyntheticLambda3.onComplete(Unknown Source:2)
        at com.google.android.gms.tasks.zzi.run(com.google.android.gms:play-services-tasks@@18.0.1:1)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at android.app.ActivityThread.main(ActivityThread.java:8751)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

上传数据和图片的核心代码如下:

private fun saveProductInformation(downloadedUrl: String) {
    auth = FirebaseAuth.getInstance()
    val uid = auth.currentUser?.uid.toString()
    databaseReference =
        FirebaseDatabase.getInstance()
            .getReference("User")
    val productName = productName.text.toString()

    val productInfo =
        DataProduk(productName, uid)
    if (uid != null) {

        databaseReference.child(uid).setValue(productInformation)
            .addOnCompleteListener {
                saveButton.isEnabled = false
                Toast.makeText(this@AddProduct,"Product added",Toast.LENGTH_SHORT).show()
                hideProgressBar()
            }
    }
}

崩溃原因

错误日志明确指向空指针异常:在调用saveButton.setEnabled(false)时,saveButton对象已变为null。

最可能的触发场景:
你上传数据后,可能提前执行了返回主页面的逻辑(比如调用finish()),导致当前Activity被销毁,视图资源被回收。而Firebase的addOnCompleteListener是异步回调,当回调执行时,saveButton对应的视图已经不存在,引用变为null,调用其方法就会引发崩溃。

另外代码还存在两个隐性问题:

  1. 变量名不一致:创建的实体是productInfo,但上传时传入的是productInformation,会导致运行错误。
  2. uid通过toString()获取,即使currentUser为null,uid也会是字符串"null",后续if (uid != null)的判断完全失效。

修复建议

  1. 在异步回调中先判断Activity状态,再操作UI:
databaseReference.child(uid).setValue(productInfo)
    .addOnCompleteListener { task ->
        // 确保Activity未被销毁再操作UI
        if (!isFinishing && !isDestroyed) {
            saveButton?.isEnabled = false
            Toast.makeText(this@TambahProduk,"Product added",Toast.LENGTH_SHORT).show()
            hideProgressBar()
            // 延迟执行页面跳转,确保UI操作完成
            Handler(Looper.getMainLooper()).postDelayed({
                finish()
            }, 1000)
        }
    }
  1. 修正变量名错误,将productInformation改为productInfo。
  2. 优化用户登录状态判断:
val uid = auth.currentUser?.uid ?: return // 用户未登录时直接终止方法执行

内容的提问来源于stack exchange,提问作者Tommy -

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:12:22