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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:49:50