为啥会跳秒??倒计时器

Posted

技术标签:

【中文标题】为啥会跳秒??倒计时器【英文标题】:Why is it skipping seconds?? CountDown timer为什么会跳秒??倒计时器 【发布时间】:2012-09-20 01:45:59 【问题描述】:

如果我的计数器超过 30 秒,它通常会在这里和那里跳过一秒钟。我让它倒计时,显示显示。但它选择跳过随机数。它每次跳过的数字都是相同的数字。如果我更改计时器的长度(用户这样做),它会更改跳过的数字。我发布了我的代码;

免责声明:这是我的第一个(有用的)应用程序,因此它可能非常糟糕或结构不佳。没关系,让我知道。我可以接受批评。但是看一看,如果有人知道为什么会丢失某些秒,请竖起大拇指。谢谢!

package com.ApphHose.runnersTimer;

//import a bunch of stuff

public class MainActivity extends Activity 
TextView text, lapNumber;
Button start;
boolean workrest, vibe;
int letsRun, lapCounter;
long length;
CountDownTimer timer;

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

    text = (TextView) findViewById(R.id.tv);
    lapNumber = (TextView) findViewById(R.id.tvLap);
    start = (Button) findViewById(R.id.bStart);
    letsRun = 2;
    lapCounter = 1;
    workrest = true;
    vibe = true;

    start.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

    start.setOnClickListener(new View.OnClickListener() 

        public void onClick(View v) 
            start.setText("Stop");
            start.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
            lapNumber.setText("Lap Number: 1");
            lapCounter = 0;
            run();
        

    );



private void run() 

    SharedPreferences getSetup = PreferenceManager
            .getDefaultSharedPreferences(getBaseContext());
    String setRun = getSetup.getString("run", "1");
    long setRunset = Long.parseLong(setRun);
    setRunset = setRunset * 1000;

    String setWalk = getSetup.getString("walk", "1");
    long setWalkset = Long.parseLong(setWalk);
    setWalkset = setWalkset * 1000;

    if (letsRun >= lapCounter) 

        if (workrest == true) 
            workrest = false;
            length = setRunset;

         else 
            workrest = true;
            length = setWalkset;
        

        final CountDownTimer timer = new CountDownTimer(length, 1000) 

            @Override
            public void onFinish() 

                if (workrest)
                    if (vibe)
                        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                        v.vibrate(2000);
                        run();
                     else 
                        run();
                    

                else
                lapCounter ++;
                lapNumber.setText("Lap Number: " + lapCounter);
                run();
                
            

            @Override
            public void onTick(long millisUntilFinished) 
                long min, sec;
                // TODO Auto-generated method stub
                min = millisUntilFinished / (60 * 1000);
                sec = (millisUntilFinished / 1000) % 60;
                String tmr = String.format("%d:%02d", min, sec);
                text.setText("" + tmr);

            

        ;
        timer.start();
        start.setOnClickListener(new View.OnClickListener() 
            //this is my button. start and stop. 
            public void onClick(View v) 
                if (start.getText() == "Stop") 
                    start.setText("Start");
                    lapCounter = 1;
                    start.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);
                    timer.cancel();
                    lapNumber.setText("Lap Number: 1");
                    text.setText("Stopped");
                 else 
                    start.setText("Stop");
                    start.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
                    run();
                
            
        );

     else 
        text.setText("Done!");
        lapCounter = 1;

    



// pop up menu
@Override
public boolean onCreateOptionsMenu(android.view.Menu menu) 
    // TODO Auto-generated method stub
    super.onCreateOptionsMenu(menu);
    MenuInflater blowUp = getMenuInflater();
    blowUp.inflate(R.menu.setup, menu);
    return true;


@Override
public boolean onOptionsItemSelected(MenuItem item) 
    // TODO Auto-generated method stub
    switch (item.getItemId()) 
    case R.id.setup:
        Intent i = new Intent("com.ApphHose.runnersTimer.SETUP");
        startActivity(i);
        break;
    case R.id.out:
        finish();
        break;
    
    return false;


【问题讨论】:

【参考方案1】:

sec = (millisUntilFinished / 1000) % 60;

整数除以整数产生整数,可能是舍入误差。

sec = (millisUntilFinished / (double) 1000) % 60;

【讨论】:

或者,long 除以 long 产生 long,视情况而定。 您需要将 millisUntil... 或 1000 提高到两倍,以便获得浮点除法。向上转换 1000 会更安全,因为它肯定适合双倍的空间。 太棒了。谢谢。我想我需要对浮点做一些研究。

以上是关于为啥会跳秒??倒计时器的主要内容,如果未能解决你的问题,请参考以下文章

为啥倒数计时器突然执行得很快?

为啥在这个循环中倒计时顺序会发生变化?

Lua/Corona SDK:为啥我的倒计时停止了?

为啥我的电脑一开机就出现关机的倒计时提示框

为啥我的计时器停止滴答作响?

为啥 QSerialPort::writeData 使用单次计时器开始写入?