【问题标题】:android stopwatch stops working when screen is off屏幕关闭时,android秒表停止工作
【发布时间】:2017-01-30 11:46:30
【问题描述】:

您好,我最近制作了一个简单的秒表应用程序,它运行良好。但是,当我切换屏幕并将其重新打开时,计时器会显示最后一个时间值。例如,如果计时器显示我 00:00:10 ,转动屏幕(持续 5 秒)重新打开它,它将显示相同的值并开始增加时间值。

有什么建议吗?

谢谢

      if (savedInstanceState != null) {
        seconds = savedInstanceState.getInt("seconds");
        running = savedInstanceState.getBoolean("running");
        wasRunning = savedInstanceState.getBoolean("wasRunning");
    }

    runTimer();
}


public void onClickStart(View view){
    running = true;
}

public void onClickStop(View view){
    running = false;
}

public void onClickReset(View view){
    running = false;
    seconds = 0;
}


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putInt("seconds", seconds);
    savedInstanceState.putBoolean("running", running);
    savedInstanceState.putBoolean("wasRunning",wasRunning);
}


@Override
protected void onPause(){
    super.onPause();
    wasRunning = running;
    running = false;
}

@Override
protected void onResume(){
    super.onResume();
    if(wasRunning){
        running = true;
    }
}

@Override
protected void onStop(){
    super.onStop();
    wasRunning = running;
    running = false;
}

@Override
protected void onStart(){
    super.onStart();
    if(wasRunning){
        running = true;
    }
}

private void runTimer(){
    final TextView timeView = (TextView)findViewById(R.id.time_view);
    final Handler handler = new Handler();

    handler.post(new Runnable() {
        @Override
        public void run() {

            int hours = seconds/3600;
            int minutes = (seconds%3600)/60;
            int secs = seconds%60;

            String time = String.format("%d:%02d:%02d",hours,minutes,secs);
            timeView.setText(time);

            if(running){
                seconds++;
            }
            handler.postDelayed(this,1000);
        }
    });

}

【问题讨论】:

    标签: android


    【解决方案1】:
    @Override
    protected void onPause(){
        super.onPause();
        wasRunning = running;
        running = false;
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        if(wasRunning){
            running = true;
        }
    }
    
    @Override
    protected void onStop(){
        super.onStop();
        wasRunning = running;
        running = false;
    }
    
    @Override
    protected void onStart(){
        super.onStart();
        if(wasRunning){
            running = true;
        }
    }
    

    只要查看您的代码,每当您的活动 PausesStops 时,您都会将 running 的值更改为 false。 并查看计时器,如果runningtrue,它只会增加值。

    【讨论】:

    【解决方案2】:

    秒表应在后台运行的服务中创建。您的 Activity 应该只读取和显示服务逻辑的超时时间。

    现在您的秒表已绑定到活动生命周期线程,因此当您的活动/应用程序处于后台时,时间计数会停止。

    参见here 一个正确的实现示例。

    【讨论】:

      【解决方案3】:

      尝试在您的清单中添加此权限

      <uses-permission android:name="android.permission.WAKE_LOCK" />
      

      【讨论】:

        【解决方案4】:

        为确保时钟一致性(您的问题 - 显示自开始以来的实时时间)和时钟准确性(避免小的累积误差),您只需测量从开始时间经过的时间:

        // first get the time in miliseconds
        long start = System.currentTimeMillis();
        

        然后在你的计时器中测量差异:

        // every now and then, get the current time and substract
        long now = System.currentTimeMillis();
        seconds = (now - start) / 1000;
        

        由于您的活动可能会被破坏并且会话数据会丢失,因此您应该在 SharedPreferences 中保存并恢复您的开始时间。您不需要其他人建议的服务。

        @Override
        protected void onCreate(Bundle state){
           super.onCreate(state);
           . . .
        
           // Restore preferences
           SharedPreferences settings = getSharedPreferences();
           start = settings.getLong("start_time", 0);
           if (start != 0) {
               running = true;
           }
        }
        
         @Override
         protected void onStop(){
         super.onStop();
         if (running) {
             SharedPreferences settings = getSharedPreferences();
             SharedPreferences.Editor editor = settings.edit();
             editor.putLong("start_time", startTime);
             editor.apply();
         }
        

        您可能很想将这些值保存在 onSaveInstanceState() Bundle 中 - 但如果您长时间不使用该应用程序,这些值将被系统销毁。 SharedPreferences 是持久的,允许您测量任何长时间。

        显然您需要在启动/停止秒表时刷新保存的 startTime。您还可以保存布尔值,这将允许您保留 startTime 和 endTime 或 timeElapsed;有很多方法可以实现这一点,但基本思想是始终测量开始时间和现在之间的时间差(或停止时间)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-10-09
          • 2023-03-12
          • 1970-01-01
          • 2016-04-18
          • 1970-01-01
          • 2013-01-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多