【问题标题】:Getting NumberFormatException in onSavedInstanceState() method [duplicate]在 onSavedInstanceState() 方法中获取 NumberFormatException [重复]
【发布时间】:2021-04-17 01:25:43
【问题描述】:

我正在使用 onSavedInstanceState() 方法,因此在旋转设备后,我的 textview 不应该失去它的价值,但我遇到了我在活动中提到的崩溃。

以下是我的活动

class SavedInstanceActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_saved_instance)

        imgPlus.setOnClickListener {
            if (tvText.text.toString().toInt() >= 10)
                tvText.text = "10"
            else
                tvText.text = tvText.text.toString().toInt().plus(1).toString()
        }

        imgMinus.setOnClickListener {
            if (tvText.text.toString().toInt() <= 0)
                tvText.text = "0"
            else
                tvText.text = tvText.text.toString().toInt().minus(1).toString()
        }

        if (savedInstanceState != null) {
            count = savedInstanceState.getInt("int", 0)
            tvText.text = count.toString()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("int", tvText.toString().toInt())  //getting crash here java.lang.NumberFormatException: For input string: "com.google.android.material.textview.MaterialTextView{12c8970 V.ED..... ........ 511,982-570,1084 #7f080174 app:id/tvText}"
        Log.d("saved", tvText.toString())
    }
}

【问题讨论】:

  • tvText 中的文本无法解析为 Int,您能粘贴 tvText 中的文本吗
  • 您需要编写 tvText.getText().toString().toInt() 因为 getText() 将传递来自 tvText 的值,否则根据您的代码 tvText 的 id 字符串将作为输出提供给您

标签: android kotlin


【解决方案1】:

您试图将 textview 转换为字符串而不是文本

像 beklow 一样尝试...

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putInt("int", tvText.text.toString().toInt()) 
    Log.d("saved", tvText.toString())
}

【讨论】:

    【解决方案2】:

    您正在使用 tvText.toString().toInt() 它应该是 tvText.text.toString().toInt() 。此外,在将文本解析为 Int 之前,您还需要检查文本是否为空。看下面的代码我做了一些修改。

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        imgPlus.setOnClickListener {
            if (tvText.text.toString().isNotEmpty() && tvText.text.toString().toInt() >= 10)
                tvText.text = "10"
            else
                tvText.text = tvText.text.toString().toInt().plus(1).toString()
        }
    
        imgMinus.setOnClickListener {
            if (tvText.text.toString().isNotEmpty() && tvText.text.toString().toInt() <= 0)
                tvText.text = "0"
            else
                tvText.text = tvText.text.toString().toInt().minus(1).toString()
        }
    
        if (savedInstanceState != null) {
            val count = savedInstanceState.getInt("int", 0)
            tvText.text = count.toString()
        }
    }
    
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        if(tvText.text.toString().isNotEmpty())
        outState.putInt("int", tvText.text.toString().toInt())
    }
    

    【讨论】:

      【解决方案3】:

      我不建议依靠文本 UI 元素来存储您的非文本应用程序状态。这有点令人费解。我会将count 保留为 Int 属性并将其与 TextView 同步。实际上,如果有的话,我会把计数放在 ViewModel 中,但为了简单起见:

      class SavedInstanceActivity : AppCompatActivity() {
      
          private var count = 0
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_saved_instance)
      
              imgPlus.setOnClickListener {
                  count = min(count + 1, 10)
                  tvText.text = count.toString()
              }
      
              imgMinus.setOnClickListener {
                  count = max(count - 1, 0)
                  tvText.text = count.toString()
              }
      
              if (savedInstanceState != null) {
                  count = savedInstanceState.getInt("int", 0)
                  tvText.text = count.toString()
              }
          }
      
          //...
      }
      

      更进一步,您可以让属性在文本视图发生更改时自动更新:

      class SavedInstanceActivity : AppCompatActivity() {
      
          private var count by Delegates.observable(0) { _, _, _ ->
              tvText.text = count.toString()
          }
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_saved_instance)
      
              imgPlus.setOnClickListener {
                  count = min(count + 1, 10)
              }
      
              imgMinus.setOnClickListener {
                  count = max(count - 1, 0)
              }
      
              if (savedInstanceState != null) {
                  count = savedInstanceState.getInt("int", 0)
              }
          }
      
          //...
      }
      

      至于您的具体问题,正如其他答案所提到的,这是因为您试图转换文本而没有安全地检查它是否可解析为 Int,如果它是空白则不是。使用toIntOrNull() 会更安全,因为它会为您提供Int?,而不是在文本无效时抛出异常。

      【讨论】:

        猜你喜欢
        • 2018-02-23
        • 1970-01-01
        • 1970-01-01
        • 2019-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-11
        • 1970-01-01
        相关资源
        最近更新 更多