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

Intent传值初次接收为null引发NumberFormatException问题求助

问题分析与解决方案

看起来你遇到的核心问题是:首次启动ViewSessionDataActivity时,通过getIntent()获取的所有Extra参数都是null,导致调用Long.parseLong(time)时触发NumberFormatException;但点击错误弹窗让Activity重启后,又能正常拿到Intent传递的正确数据。

问题根源

从日志和代码来看,你是在Service中使用FLAG_ACTIVITY_NEW_TASK启动Activity。如果ViewSessionDataActivity已经存在于当前任务栈中,Android默认会复用已有的Activity实例,而不是创建新实例——这时候getIntent()返回的是第一次启动该Activity时的旧Intent(大概率是没有携带Extra的空Intent),所以初次获取时全为null;而错误弹窗导致Activity重启后,系统会创建新实例,此时才会接收新传递的Intent数据。

解决方案

方案1:处理Activity复用场景,更新Intent

在ViewSessionDataActivity中重写onNewIntent()方法,确保复用实例时能拿到最新的Intent,同时抽离数据初始化逻辑做统一处理:

private DateFormat dateFormat;
private TextView distance_view, speed_view, time_view;
private String distance, speed;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_session_data);
    dateFormat = new SimpleDateFormat("dd/MM/yyy 'at' hh:mm aaa");
    
    // 初始化View
    distance_view = findViewById(R.id.distance);
    speed_view = findViewById(R.id.speed);
    time_view = findViewById(R.id.time);
    save_button = findViewById(R.id.save_button);
    delete_button = findViewById(R.id.delete_button);
    
    // 从Intent加载数据
    initDataFromIntent(getIntent());
}

// 重写onNewIntent,接收新的Intent并更新
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent); // 替换旧的Intent为新传递的Intent
    initDataFromIntent(intent); // 重新加载数据
}

// 抽离数据初始化逻辑,统一处理
private void initDataFromIntent(Intent intent) {
    if (intent == null) {
        Log.w("ViewSessionData", "Intent is null, skip data loading");
        return;
    }
    
    distance = intent.getStringExtra("DISTANCE");
    String time = intent.getStringExtra("TIME");
    speed = intent.getStringExtra("SPEED");
    
    Log.d("distance =", "" + distance);
    Log.d("time1 =", "" + time);
    Log.d("speed =", "" + speed);
    
    // 强制非空校验,避免崩溃
    if (time == null || time.trim().isEmpty()) {
        time_view.setText("00:00");
        distance_view.setText("0.00 Km");
        speed_view.setText("0.00 m/s");
        return;
    }
    
    try {
        final long time1 = Long.parseLong(time);
        final String dateStr = dateFormat.format(Calendar.getInstance().getTime());
        
        Log.d("distance","" + distance);
        Log.d("time","" + time1);
        Log.d("speed","" + speed);
        Log.d("date", dateStr);
        
        // 更新UI
        distance_view.setText(distance + " Km");
        speed_view.setText(speed + " m/s");
        time_view.setText(getDurationBreakdown(time1));
    } catch (NumberFormatException e) {
        Log.e("ViewSessionData", "Failed to parse time: " + time, e);
        time_view.setText("Invalid time");
    }
}

方案2:启动时强制创建新实例

如果你不需要复用ViewSessionDataActivity的旧实例,可以在发送Intent时添加FLAG_ACTIVITY_CLEAR_TOP标志,确保销毁栈中已存在的实例并创建新实例:

public void onLogEnd(){
    // ... 你的原有计算逻辑 ...
    
    Intent i = new Intent();
    i.setClass(MyBoundService.this, ViewSessionDataActivity.class);
    // 组合FLAG,确保创建新实例
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.putExtra("DISTANCE", convertDistance(distance));
    i.putExtra("TIME", time1);
    i.putExtra("SPEED", formatSpeed(avgSpeed));
    startActivity(i);
}

方案3:发送端确保Extra非空

检查convertDistance()和formatSpeed()方法,确保它们返回的字符串永远不为null。例如:

private String convertDistance(Float distance) {
    if (distance == null) {
        return "0.00";
    }
    // 你的原有转换逻辑
    return String.format("%.2f", distance / 1000);
}

private String formatSpeed(double avgSpeed) {
    return String.format("%.2f", avgSpeed);
}

总结

最稳妥的方式是方案1 + 方案3:既处理Activity复用导致的Intent旧数据问题,又通过非空校验和异常捕获避免崩溃,同时确保发送端传递的Extra不会为null。

内容的提问来源于stack exchange,提问作者Tristan O'Keefe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:56:11