如何用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
相关产品推荐
相关产品推荐

