【问题标题】:Updating TextView with timer onTick after leaving and returning to activity离开并返回活动后使用计时器 onTick 更新 TextView
【发布时间】:2016-12-30 14:21:45
【问题描述】:

我正在编写一个锻炼应用程序,并尝试在 Train 活动中实现一个休息计时器。 CountDownTimer 位于Train 内,当用户按下开始按钮时调用。

public CountDownTimer createTimer(long timerDuration) {

    Log.d("new timer duration:", "value: " + timerDuration);
    return new CountDownTimer(timerDuration, 1000) {

        @Override
        public void onTick(long millisUntilFinished) {
            int progress = (int) (millisUntilFinished / 1000);
            secondsLeftOnTimer = progress;  // update variable for rest of app to access

            // Update the output text
            breakTimerOutput.setText(secondsToString(progress));
        }

        @Override
        public void onFinish() { // Play a beep on timer finish
            breakTimerOutput.setText(secondsToString(timerDurationSeconds));
            playAlertSound();  // TODO: Fix the delay before playing beep.
        }
    }.start();
}

只要用户停留在Train 活动中,计时器就会工作。如果切换到另一个活动,计时器会继续在后台运行(仍然会发出哔声),这就是我想要的。但是,如果您返回到 Train 活动,breakTimerOutput TextView 将不再由 onTick 更新。

当用户重新进入Train 活动时,我如何将breakTimerOutput“重新连接”到onTick

Here is the full code for the activity, just in case.

【问题讨论】:

  • 您是否考虑过您的 Train Activity 的 onPause 和 onResume?
  • 我没有,但这是一个想法。离开活动时我基本上会存储计时器吗?我是 Android 编程新手,所以我对通常如何处理这样的事情有点生疏。

标签: java android android-activity countdowntimer


【解决方案1】:

我想建议将计时器保留在Service 中,并使用BroadcastReceiver 接收更新TrainActivity 中的TextView 的刻度。

您需要从Service 启动CountDownTimer。所以在ServiceonCreate 方法中,你需要初始化一个LocalBroadcastManager

broadcastManager = LocalBroadcastManager.getInstance(this);

因此,在您的计时器(即onTick 方法)的每个滴答声中,您可能会考虑调用这样的函数。

static final public String UPDATE_TIME = "UPDATE_TIME";
static final public String UPDATED_TIME = "UPDATED_TIME";

public void updateTextView(String time) {
    Intent intent = new Intent(UPDATE_TIME);
    if(time != null)
        intent.putExtra(UPDATED_TIME, time);
    broadcastManager.sendBroadcast(intent);
}

现在在您的TrainActivity 中创建一个BroadcastReceiver

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.setContentView(R.layout.copa);
    receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String time = intent.getStringExtra(YourService.UPDATED_TIME);
            // Update your TextView here.
        }
    };
}

此外,您还需要注册和注销BroadcastReceiver

@Override
protected void onStart() {
    super.onStart();
    LocalBroadcastManager.getInstance(this).registerReceiver((receiver), 
        new IntentFilter(YourService.UPDATE_TIME)
    );
}

@Override
protected void onStop() {
    LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
    super.onStop();
}

【讨论】:

  • 谢谢!这看起来不错。我会试一试。我是否正确假设您最后一节中的代码进入Train 活动?
  • 是的,ReceiveronStartonStop 属于 TrainActivity
  • 谢谢!最后,我将receiver 定义为BroadcastReceiver receiver,对吗?这样做似乎会导致您的最后一段代码出现问题,LocalBroadcastManager.getInstance(this).registerReceiver(receiver), new IntentFilter(BreakTimer.UPDATE_TIME);
  • 是的。您需要先创建一个名为 receiver 的变量。
  • 我不想打扰你。我真的很感谢你的帮助,但我似乎无法弄清楚。我已将倒数计时器的代码添加到服务中,但无法弄清楚如何从活动中启动它。我从来没有使用过服务,所以我真的不知道如何访问它。 Here's the service.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 2017-08-09
  • 2013-12-03
  • 2018-03-04
  • 1970-01-01
相关资源
最近更新 更多