android倒计时-上次点击未调用-使用什么干净的解决方案?

android倒计时-上次点击未调用-使用什么干净的解决方案?,android,timer,countdown,Android,Timer,Countdown,挫折贴 我刚刚偶然发现了许多人在这里报告的“倒计时-最后一次点击未调用”问题 显示问题的简单演示 package com.example.gosh; import android.app.Activity; import android.os.Bundle; import android.os.CountDownTimer; import android.util.Log; public class CountDownTimerSucksActivity extends Activity {

挫折贴

我刚刚偶然发现了许多人在这里报告的“倒计时-最后一次点击未调用”问题

显示问题的简单演示

package com.example.gosh;

import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;

public class CountDownTimerSucksActivity extends Activity {

int iDontWantThis = 0; // choose 100 and it works yet ...

private static final String TAG = "CountDownTimerSucksActivity";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    new MyCountDownTimer(10000 + iDontWantThis , 1000).start();
}

class MyCountDownTimer extends CountDownTimer {

    long startSec;

    public MyCountDownTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        // TODO Auto-generated constructor stub
        startSec = System.currentTimeMillis() ;
    }

    @Override
    public void onFinish() {
        // TODO Auto-generated method stub
        Log.e(TAG, " onFinish (" + getSeconds() + ")");
    }

    @Override
    public void onTick(long millisUntilFinished) {
        // TODO Auto-generated method stub
        Log.e(TAG, millisUntilFinished + " millisUntilFinished" + " (" + getSeconds() + ")");

    }

    protected long getSeconds() {
        return  (((System.currentTimeMillis() - startSec) / 1000) % 60);

    }

}

}
测试运行的logcat输出

正如您所看到的,上一次调用onTick的时间是1963ms毫秒,直到完成,然后下一次调用在大约2秒后完成。肯定是一种令人讨厌的行为。我发现很多关于这个的帖子还没有一个干净的解决方案。我在源代码中包含了一个,如果您将IDONTWANT字段设置为100,它将正常工作

我不介意在次要领域的变通办法,但这似乎是一个核心功能,我无法理解它还没有被修复。你们这些人在做什么来获得一个干净的解决方案

非常感谢

马丁

更新:


Sam对倒数计时器进行了非常有用的修改,该修改不会因内部毫秒延迟而超过最后一个刻度,也可以防止毫秒延迟随着时间的推移而累积。

您所经历的行为实际上在
倒数计时器中明确定义

请注意,在
handleMessage()
中,如果剩余时间小于间隔,它将显式地不调用
onTick()
,而只是延迟到完成


不过,请注意,从源代码看,
CountdownTimer
只是
处理程序
上的一个非常薄的包装,它是Android框架的实时组件。作为一种解决方法,您可以很容易地从这个来源(少于150行)创建自己的计时器,并删除此限制以获得最终的滴答声回调。

我认为挫败感来自对滴答声应该是什么的错误预期。另一个答案指出,这种行为是故意的。另一种可能的处理方法是简单地指定一个较小的间隔。例如,如果您正在实现某种倒计时时钟,那么将时间间隔更改为500也无妨。如果某些工作仅在秒数变化时完成很重要,那么您也可以通过存储
getSeconds()
的结果并仅在该值变化时执行该工作来完成


如果
CountdownTimer
被更改为始终触发最后一个滴答声,即使剩余时间小于间隔,我肯定StackOverflow会有一大堆问题,比如“为什么我在
CountdownTimer
的最后一个滴答声中没有足够的时间?”

我不明白你为什么说这是故意行为,API确切地说:

将倒计时安排到将来某个时间,并定期通知沿途的时间间隔

如果您将时间设置为30秒,并将倒计时间隔设置为1000,正如API所说的常规,那么应该正好触发30次。 我认为这不是故意的行为,而是错误的实现

解决方案应为Sam在此提出的解决方案:

Android的调用onTick()计时器一启动(毫不延迟)(如图所示),这是第一次

在此之后,将根据计时器完成之前的剩余时间调用onTick()

如果计时器完成之前的剩余时间小于指定的时间间隔,则不会调用onTick()。这就是没有调用上一个onTick()的原因

修改的倒计时类 我修改了计时器,在指定的延迟之后调用onTick()所有间隔(包括第一个和最后一个)。这是上课时间-

公共抽象类倒计时{
私人最终长远计划;
私人最终长时间间隔;
私人长期信息;
私有布尔值mCancelled=false;
公共倒计时(长毫秒未来,长倒计时间隔){
mMillisInFuture=millisInFuture;
mCountdownInterval=倒计时间隔;
}
公共同步最终作废取消(){
McCancell=true;
mHandler.removeMessages(MSG);
}
公共同步最终倒计时开始(){
mCancelled=false;

如果(mMillisInFuture)你是对的,我只是期待不同的行为,这是挫折的根源。我很惊讶API文档中没有提到预期的行为,特别是在上面的日志中,可以看到倒计时计时器,它实际上是“晚了”每一个勾号都比给定的秒间隔延迟47毫秒,正是这47毫秒导致onTick没有按我的预期被调用。想象一下,你给4小时作为间隔,谁会期望onTick因为43毫秒而没有被调用。但这是预期的问题;)非常感谢,android是一个新手,我还没有采取措施在这种情况下查看它的源代码。非常感谢你告诉我这一步。我将按照建议实现我自己的倒计时程序,如果millisuntilfeigned>0,它总是调用onTick,我可以很容易地检查剩余的millis是否允许我想做的事情(实际上,我只需要显示6,5,4,3,2,1,0的倒计时计时器)只是为了完整起见,删除下面的else if块,以便在有毫秒剩余时调用onTick-------------------------------------------}else if(millisLeftnew CountDownTimer(30000, 1000) { public void onTick(long millisUntilFinished) { mTextField.setText("seconds remaining: " + millisUntilFinished / 1000); } public void onFinish() { mTextField.setText("done!"); } }.start();