【问题标题】:App crashes, seemingly because of EditText to String to Double/Long conversion应用程序崩溃,似乎是因为 EditText 到 String 到 Double/Long 的转换
【发布时间】:2021-04-02 12:27:30
【问题描述】:

我需要在 Room 数据库中输入一些值。为此,我需要将用户输入的任何内容转换为 Double 和 Long。由于某种原因,每次我尝试执行此操作时应用程序都会崩溃。我相当确定问题出在标有//Need to fix 的两个变量中,因为我尝试将它们初始化为0,之后应用程序运行良好。如果需要,我很乐意提供更多信息。这可能是什么问题?

这是代码:

    override fun onResume() {
    super.onResume()

    var transacType = false
    var transacAmount = binding.amountInput.text.toString().toDouble()          //Need to fix
    var transacDate: Long = binding.pickedDate.text.toString().toLong()         //Need to fix
    var transacCategory: String = "N"
    val duration = Toast.LENGTH_SHORT

    ...

    binding.floatingActionButton.setOnClickListener{
        if (transacCategory == "N" || transacCategory == "Pick a category…" && binding.spinner2.isVisible) {

            val text = "Please pick a category!"
            val toast = Toast.makeText(applicationContext, text, duration)
            toast.show()
        } else if (transacAmount == 0.0) {

            val text = "Please input an amount!"
            val toast = Toast.makeText(applicationContext, text, duration)
            toast.show()
        } else {

            val transaction = Transactions(0L, transacType, transacAmount, transacDate, transacCategory)
            transactionViewModel.insert(transaction)
        }
    }

我不确定是否有必要,但这是日志中我不知道如何阅读的所有红色内容:

2021-04-02 17:25:54.438 22619-22619/com.example.budgie E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.budgie, PID: 22619
java.lang.RuntimeException: Unable to resume activity {com.example.budgie/com.example.budgie.AddTransactionActivity}: java.lang.NumberFormatException: empty String
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4789)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4832)
    at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:8178)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
 Caused by: java.lang.NumberFormatException: empty String
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
    at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(Double.java:538)
    at com.example.budgie.AddTransactionActivity.onResume(AddTransactionActivity.kt:72)
    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1465)
    at android.app.Activity.performResume(Activity.java:8223)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4779)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4832) 
    at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:213) 
    at android.app.ActivityThread.main(ActivityThread.java:8178) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101) 

PS。我知道我的代码中可能还有其他问题,但现在我只是想解决这个问题。

PSS。我是新人,请放轻松好吗?

【问题讨论】:

    标签: android android-studio kotlin android-room


    【解决方案1】:

    你已经得到了答案,但只是为了解释人们是如何知道的(这样你也可以调查谜团)......

    日志中的红色文本是堆栈跟踪 - 当您遇到导致应用程序崩溃的异常(一种错误)时打印它,并显示它在哪一行崩溃,导致它的方法链,以及导致坠机的原因。这样您就可以了解发生了什么以及需要查看的位置!

    分块排列,第一个以

    开头
    java.lang.RuntimeException: Unable to resume activity [...]
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4789)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4832)
        ...
    

    所以您的应用程序因RuntimeException 而崩溃,并且它包含的消息(基本上是解释)是“无法恢复活动”。下一行表示异常是在performResumeActivity()ActivityThread.java 的第4789 行引发的,而您从同一文件中handleResumeActivity() 的第4832 行到达那里,等等...


    有时这很有用,在这种情况下,这都是你没有编写的所有 Android 内部的东西,所以让我们看看下一个块,这是抛出的异常,它让 performResumeActivity 放弃并抛出它的异常:

    Caused by: java.lang.NumberFormatException: For input string: "com.google.android.material.textfield.TextInputEditText{64a283 VFED..CL. ......I. 0,0-0,0 #7f09004a app:id/amount_input}"
    

    与之前的交易相同,但我们无需深入研究 - 我们在这里拥有所需的所有信息!这个NumberFormatException 导致外部RuntimeException 导致应用程序崩溃。 NumberFormatExceptions 通常会在您尝试将某些文本读取为数字时出现,但它不符合合法格式 - 它会告诉您导致它的输入字符串,这绝对不能作为数字读取!

    如果您查看该块中的堆栈跟踪,您会看到这一点:

    at java.lang.Double.parseDouble(Double.java:538)
    at com.example.budgie.AddTransactionActivity.onResume(AddTransactionActivity.kt:72)
    

    这告诉您正在抛出的parseDouble() 调用正在AddTransactionActivity 的第72 行调用,这基本上指向您自己的代码中问题所在(或开始)的位置。 (它有助于扫描跟踪,直到您发现 com.example.budgie 或任何您的包名称,这样您就可以找到实际代码涉及的位置。)

    因此,即使您不知道错误的确切原因,您也知道该看什么!你知道你传递了错误的输入字符串——它应该是TextView 中的一个数字,但它是一些东西。您可能不知道所有这些东西是什么,但希望您在其中看到“TextView”,并意识到TextView 本身以某种方式参与其中,而您没有得到文本内容。然后你可以去看看,看看你做得对不对......

    别担心,textView.text 的事情也经常让我绊倒。是的,输入字符串打印在堆栈跟踪的第一行(RuntimeException 正在打印其原因的消息)但我想表明您可以分别查看每个块,并阅读跟踪以找出事情确实发生了

    希望对您或其他人有所帮助!

    【讨论】:

    • 非常感谢!它确实帮助我理解了如何找到问题并识别它,并且在将.text 添加到这些变量的初始声明之后,堆栈跟踪发生了变化。现在它说Caused by: java.lang.NumberFormatException: empty String。至少我会有所收获!
    • 希望这个更明显 ;) Kotlin 有一堆 ...OrNull 函数,比如 toDoubleOrNull,它们产生 null 值而不是抛出异常,所以你可以处理错误那样。您在这里更广泛的问题是您开始时输入框中没有数据,因此您需要决定如何处理这种情况。我建议使用某种验证器功能,检查用户输入的内容是否可以实际使用,然后再尝试使用它!这样你就可以处理启动和未来的恶作剧
    【解决方案2】:

    binding.amountInput 是 EditText 的类型,您尝试在 EditText 上执行 toString() 而不是 edittext 中的文本。因为它是对象类型,所以 toString 只是打印它的类型 com.google.android.material.textfield.TextInputEditText 然后尝试将此字符串转换为数字,这会导致异常。你需要做的是: var transacAmount = binding.amountInput.text.toString().toDouble()

    【讨论】:

    • 好的,所以我修复了那部分代码,但由于某种原因,当应该打开 EditText 的屏幕时它仍然崩溃。不过,感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-09-30
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多