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

如何用SharedPreferences保存Chronometer时间并在另一Activity读取

解决Chronometer起始时间跨Activity保存与读取问题

我来帮你搞定这个Chronometer跨Activity保存和读取的问题!你的思路是对的,用SharedPreferences确实比Service简单直接,咱们先梳理现有代码里的问题,再一步步修正。

现有代码的核心问题

  • 保存的起始时间计算错误:你在MainActivity里计算的startTime = (SystemClock.elapsedRealtime() - chronometer.getBase())其实是0,因为你刚把chronometer的base设为当前SystemClock.elapsedRealtime(),两者差值为0,等于没保存有效数据。
  • SecondActivity中设置base的逻辑错误:直接把读取到的savedTime设为chronometer的base,没有遵循Chronometer的计时逻辑,导致无法正确显示累计时间。

修正后的MainActivity代码

首先,我们要在Chronometer启动时,正确保存它的base值(这才是计时的起始基准):

public class MainActivity extends AppCompatActivity{
    private Chronometer chronometer;
    protected FirebaseAuth firebaseauth = FirebaseAuth.getInstance();
    // 确保Firebase引用已初始化
    private DatabaseReference mChildReference1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_main_layout); // 替换为你的布局ID
        chronometer = findViewById(R.id.your_chronometer_id); // 初始化Chronometer
        // 初始化Firebase引用,示例:
        mChildReference1 = FirebaseDatabase.getInstance().getReference("your_path");
    }

    @Override
    protected void onStart(){
        super.onStart();
        final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        final SharedPreferences.Editor editor = pref.edit();

        mChildReference1.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange (DataSnapshot dataSnapshot){
                String status = dataSnapshot.getValue(String.class);
                if (status != null && status.equals ("occupied")) {
                    // 设置Chronometer的基准时间为当前系统流逝时间
                    long startBase = SystemClock.elapsedRealtime();
                    chronometer.setBase(startBase);
                    chronometer.start();
                    // 保存基准时间到SharedPreferences
                    editor.putLong("chronometer_base", startBase);
                    editor.apply(); // 异步保存,比commit()更高效
                } else {
                    // 状态非occupied时停止计时并重置
                    chronometer.stop();
                    chronometer.setBase(SystemClock.elapsedRealtime());
                    // 清空保存的基准值
                    editor.remove("chronometer_base");
                    editor.apply();
                    mValueView1.setBackgroundColor(Color.parseColor("#66d983"));
                }
            }

            @Override
            public void onCancelled (DatabaseError databaseError){
                // 可选:添加错误提示,比如Toast.makeText(MainActivity.this, "读取数据失败", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

修正后的SecondActivity代码

在SecondActivity中,读取保存的基准时间,正确设置给Chronometer以继续累计计时:

public class SecondActivity extends AppCompatActivity{
    private Chronometer chronometer;
    private DatabaseReference mChildReference1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_second_layout); // 替换为你的布局ID
        chronometer = findViewById(R.id.your_second_chronometer_id); // 初始化Chronometer
        // 初始化Firebase引用
        mChildReference1 = FirebaseDatabase.getInstance().getReference("your_path");
    }

    @Override
    protected void onStart() {
        super.onStart();
        final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);

        mChildReference1.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String status = dataSnapshot.getValue(String.class);
                if(status != null && status.equals("occupied")) {
                    // 读取保存的基准时间,默认值设为当前系统时间(无保存则从0开始)
                    long savedBase = pref.getLong("chronometer_base", SystemClock.elapsedRealtime());
                    // 设置Chronometer的基准为保存的值
                    chronometer.setBase(savedBase);
                    chronometer.start();
                    chronometer.setVisibility(View.VISIBLE);
                } else {
                    // 状态非occupied时停止并重置计时
                    chronometer.stop();
                    chronometer.setBase(SystemClock.elapsedRealtime());
                    chronometer.setVisibility(View.GONE);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                // 错误提示逻辑
            }
        });
    }
}

关键逻辑说明

  • Chronometer的计时原理是:显示时间 = SystemClock.elapsedRealtime() - getBase(),所以只要保存初始的getBase()值,在另一个Activity里设置回去,就能继续累计计时。
  • 用editor.apply()代替commit():apply()是异步保存,不会阻塞主线程,性能更优;commit()是同步操作,仅适合需要立即确认保存结果的场景。
  • 务必补充Chronometer和Firebase引用的初始化代码,原代码存在缺失,需根据你的实际布局和Firebase路径调整。

内容的提问来源于stack exchange,提问作者Anonymous

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:38:26