【问题标题】:Resuming CountdownTimer after rotation旋转后恢复 CountdownTimer
【发布时间】:2012-07-06 18:56:17
【问题描述】:

我有一个从 60 秒开始倒计时的 CountdownTimer。这个 CountdownTimer 通过将 textView 设置为剩余毫秒来工作,但是每当我旋转我的设备时,CountdownTimer 都会重置。

我知道发生这种情况是因为 Activity 会在轮换时重新启动。所以我尝试保存捆绑包中剩余的时间,然后在 Activity 重新启动后恢复它。

long transferValue;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_playtimemode);

    Log.d("Debug", "onCreate: " + transferValue);

    long setTime = 60000;
    long difference = setTime - transferValue;

    new CountDownTimer(difference, 1000) {

        public void onTick(long millisUntilFinished) {
            millisUntilFinishedToSave = millisUntilFinished;
            tvCountdown.setText("" + millisUntilFinished / 1000);
        }

        public void onFinish() {
            tvCountdown.setText("done!");
        }
    }.start();

}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putLong("millisKey", millisUntilFinishedToSave);

}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    transferValue = savedInstanceState.getLong("millisKey");
    Log.d("Debug", "onRestoreInstanceState(): " + transferValue);
}

但这不起作用。我在这段代码的顶部初始化 transferValue(因此它返回 0),但是我怎样才能将数据从 savedInstanceState 保存到 CountdownTimer?

07-06 20:21:30.038: D/Debug(28995): onCreate: 0
07-06 20:21:30.043: D/Debug(28995): onRestoreInstanceState(): 55994

【问题讨论】:

    标签: java android countdowntimer


    【解决方案1】:

    我会给你的计时器它自己的线程。您的计时器正在停止,因为它位于 UI 线程上(如您所述),并且当 UI 重绘时,Activity 会重新初始化。所有长时间运行的进程都应该有自己的线程。经验法则:尽快退出 UI 线程。

    这是使用服务的示例。此服务将在调用时启动并保留在内存中,而不管屏幕方向变化甚至活动焦点变化。

    这里是服务:

    public class Timer extends Service {
    
        @Override
        public IBinder onBind(Intent i) {
            return null;
        }
        @Override
        public int onStartCommand(Intent i, int flags, int startId) {
            // Put your timer code here
        }
    }
    

    您需要将此行添加到清单中(在应用程序打开/关闭标记之间的某个位置):

    <service android:name=".Timer" />
    

    然后你就可以使用这个随时启动服务了(需要注意的是可以反复启动,递归调用不会产生新的服务):

    startService(new Intent(this, Timer.class));
    

    【讨论】:

    • 你能给我一个代码sn-p吗?计时器应在旋转开始时停止倒计时,然后在旋转完成时恢复。这可能吗?
    • Matt Westlake 的实现更加紧凑,这样做可以节省空间。但是,如果您将有多个计时器或需要访问不同类中的值,那么请选择我的答案。我将编辑我的帖子以显示一些代码。
    • 当心这个常见的误解 - Service 在主 UI 线程上运行,而不是后台线程。
    【解决方案2】:

    使用 System.currentTimeMillis 获取当前系统时间,然后将 60000 毫秒添加到时间并将其存储为结束时间。然后,任何时候您必须更改任何内容,只需将 System.currentTimeMillis 与 EndTime 进行比较即可。

    Endtime = System.currentTimeMillis + 60000;
    

    然后在每个实例上

    TimeRemaining = Endtime - System.currentTimeMillis
    

    【讨论】:

    • 所以我不使用倒计时?
    • 这个答案没有获得足够的信用。我喜欢它
    【解决方案3】:

    接受的答案使事情变得非常复杂。你可以用更简单的方式来做。代码中的问题是 Activity 是在轮换时创建的(请参阅 Activity 生命周期),CountdownTimer 实例也是如此。

    我可以编写整个示例代码,但@Drew 在这里给出了一个很好的答案:Android Innerclass TextView reference when activity resumes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多