Android应用解析Intent字符串为Double时抛出IllegalStateException崩溃
Android健康计算应用Intent传值崩溃问题修复
问题背景
我正在开发一款Android健康计算应用,功能是收集用户体重、身高、性别等信息,计算IMC(身体质量指数)、TMB(基础代谢率)、卡路里等指标,包含3个Activity:
- MainActivity:收集用户输入数据,通过Intent传递给SeeResults
- SeeResults:计算并展示IMC、TMB等结果,需要将TMB和体重传递给第三个Activity
- CalcularDefinicion:接收TMB和体重,计算用户每月摄入指定卡路里后的减重数值
崩溃现象:在CalcularDefinicion中解析Intent传递的TMB和体重字符串为Double类型时,应用抛出IllegalStateException并崩溃。查看StackTrace可知,根本原因是NullPointerException——尝试对null对象调用trim()方法,说明获取到的TMB或体重字符串为null。
错误原因
SeeResults的onCreate方法中,错误地将计算得到的TMB和Peso添加到了接收自MainActivity的Intent中,而非启动CalcularDefinicion的新Intent。导致跳转时CalcularDefinicion拿到的Intent里没有这两个参数,解析时触发空指针异常。
修复方案
在SeeResults的calcularDefinicion方法中,创建跳转CalcularDefinicion的Intent时,添加TMB和Peso的Extra参数,而不是在onCreate中修改旧Intent。同时修复代码中的其他语法问题。
修改后的关键代码
1. 修复SeeResults代码
public class SeeResults extends AppCompatActivity { private double calculatedTMB; private double userWeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_see_results); dataTransfered = new String[6]; TextView imc = findViewById(R.id.Imc); Intent receivedIntent = getIntent(); String [] data = receivedIntent.getStringArrayExtra("data"); dataTransfered = data; String actividadF = dataTransfered[4]; String genero = dataTransfered[5]; double actividadFNumero = 0; switch (actividadF) { case "Poca": actividadFNumero = 1.1; break; case "Regular": actividadFNumero = 1.3; break; case "Bastante": actividadFNumero = 1.5; break; case "Mucha": actividadFNumero = 1.7; break; } userWeight = Double.parseDouble(dataTransfered[3]); double altura = Double.parseDouble(dataTransfered[2]) / 100; int edad = Integer.parseInt(dataTransfered [1]); double IMC = Math.round (userWeight / (altura * altura)); calculatedTMB = 0; if (genero.equals("hombre")) { calculatedTMB = ((10 * userWeight) + (6.25 * (altura * 100) ) - (5 * edad ) + 5) * actividadFNumero; } if (genero.equals("mujer")) { calculatedTMB = ((10 * userWeight) + (6.25 * (altura * 100) ) - (5 * edad) - 161) * actividadFNumero; } Log.d("ActividadFisica",actividadF); Log.d("ActividadFisicaNumero", String.valueOf(actividadFNumero)); Log.d("Genero",genero); imc.setText("Tu IMC es : " + IMC + "\n" + "Tu TMB es : " + calculatedTMB + "\n" + "\n" + "Calorias definición : " + (calculatedTMB - 500) + "\n" + "\n" + "Calorias en volumen: " + (calculatedTMB + 500)); } public void goBack (View v) { Intent i = new Intent(this,MainActivity.class); startActivity(i); } public void calcularDefinicion (View v) { Intent intentToDef = new Intent(this, CalcularDefinicion.class); // 在这里添加需要传递的参数 intentToDef.putExtra("TMB", String.valueOf(calculatedTMB)); intentToDef.putExtra("Peso", String.valueOf(userWeight)); startActivity(intentToDef); } String [] dataTransfered; }
修改说明:
- 把计算得到的TMB和体重保存为类成员变量
calculatedTMB和userWeight,方便在跳转方法中使用 - 删除onCreate中给旧Intent加参数的代码
- 在
calcularDefinicion方法中创建新Intent,并添加TMB和Peso的Extra参数
2. 修复MainActivity中的语法错误
原代码中replace方法的括号未闭合,导致编译错误,修改后:
// 原错误代码 // String edadN = edad.getText().toString().replace("Edad",""; // String alturaN = altura.getText().toString().replace("Altura",""; // String pesoN = peso.getText().toString().replace("Peso",""; // 修改后 String edadN = edad.getText().toString().replace("Edad", ""); String alturaN = altura.getText().toString().replace("Altura", ""); String pesoN = peso.getText().toString().replace("Peso", "");
3. CalcularDefinicion添加空值判断(可选但推荐)
为避免后续空指针,在解析前先检查参数是否存在:
public void calcularDef (View v) { int calorias = Integer.parseInt(caloriasDef.getText().toString().replace("Calorias","")); int tiempo = Integer.parseInt(tiempoDef.getText().toString().replace("Tiempo","")); Log.d("caloriasNumero",String.valueOf(calorias)); Log.d("tiempoNumero",String.valueOf(tiempo)); Intent i = getIntent(); String tmbStr = i.getStringExtra("TMB"); String pesoStr = i.getStringExtra("Peso"); // 空值判断 if (tmbStr == null || pesoStr == null) { Toast.makeText(this, "数据传递错误,请返回重试", Toast.LENGTH_SHORT).show(); return; } double TMB = Double.parseDouble(tmbStr); double peso = Double.parseDouble(pesoStr); Log.d("TMB",String.valueOf(TMB)); Log.d("Peso",String.valueOf(peso)); // 注意:tiempo是int,tiempo/30会是整数除法,需转成double double pesoPerdido = (TMB - calorias) * ((double)tiempo / 30); double pesoFinal = peso - pesoPerdido; textoAcabar.setText(textoAcabar.getText() + " " + pesoFinal); }
额外修复:原代码中tiempo / 30是整数除法,会丢失小数精度,改为(double)tiempo / 30确保浮点运算。
错误栈信息
FATAL EXCEPTION: main Process: com.example.calculoimc, PID: 32693 java.lang.IllegalStateException: Could not execute method for android:onClick at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:473) at android.view.View.performClick(View.java:7506) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1211) at android.view.View.performClickInternal(View.java:7483) at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0) at android.view.View$PerformClick.run(View.java:29334) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7872) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468) ... 12 more Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference at jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1838) at jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110) at java.lang.Double.parseDouble(Double.java:543) at com.example.calculoimc.CalcularDefinicion.calcularDef(CalcularDefinicion.java:31) ... 14 more
内容的提问来源于stack exchange,提问作者Rober
相关产品推荐
相关产品推荐

