在Android中停止秒表

时间:2014-11-25 06:20:16

标签: java android multithreading button stopwatch

我制作了一个自定义秒表,显示小时:分钟:秒。控制由START和STOP按钮给出。但是,停止秒表时出现问题。当秒表停止时它没有停止。单击“停止”按钮。任何人请建议我正确的解决方案。

    package com.example.mystopwatch;


import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class StopwatchActivity extends Activity {
private TextView textViewTimer;
private Button BtnStart,BtnStop;
private Handler mHandler = new Handler();
private long startTime;
private long elapsedTime;
private final int REFRESH_RATE = 100;
private String hours,minutes,seconds,milliseconds;
private long secs,mins,hrs,msecs;
private boolean stopped = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_stopwatch);
    BtnStart=(Button)findViewById(R.id.startbtn);
    BtnStop=(Button)findViewById(R.id.stopbtn);
    BtnStart.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
             Runnable startTimer1 = new Runnable() 
            { 
                public void run() 
                {
                    elapsedTime = System.currentTimeMillis() - startTime; updateTimer(elapsedTime);
                    mHandler.postDelayed(this,REFRESH_RATE); 
                    }


                };
             if(stopped)
             {
                 startTime = System.currentTimeMillis() - elapsedTime;
                 } 
             else
             { 
                 startTime = System.currentTimeMillis(); 
                 } 
             mHandler.removeCallbacks(startTimer1);
             mHandler.postDelayed(startTimer1, 0);


        }
                });
    BtnStop.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
             Runnable startTimer2 = new Runnable() 
                { 
                    public void run() 
                    {
                        elapsedTime = System.currentTimeMillis() - startTime; updateTimer(elapsedTime);
                        mHandler.postDelayed(this,REFRESH_RATE); 
                        }


                    };

            mHandler.removeCallbacks(startTimer2);
            stopped = true;

        }
    });

}   
private void updateTimer(long time) {
    // TODO Auto-generated method stub

        secs = (long)(time/1000); 
    mins = (long)((time/1000)/60);
    hrs = (long)(((time/1000)/60)/60); 
    secs = secs % 60; 
    seconds=String.valueOf(secs);
    if(secs == 0)
    { 
        seconds = "00";

    } 
    if(secs <10 && secs > 0)
    { 
        seconds = "0"+seconds; 
        }
    mins = mins % 60;
    minutes=String.valueOf(mins);
    if(mins == 0){ minutes = "00";
    } 
    if(mins <10 && mins > 0)
    {
        minutes = "0"+minutes;
        }
    hours=String.valueOf(hrs);
    if(hrs == 0)
    { 
        hours = "00";
        }
    if(hrs <10 && hrs > 0)
    {
        hours = "0"+hours;
        }
     milliseconds = String.valueOf((long)time);
     if(milliseconds.length()==2)
     {
         milliseconds = "0"+milliseconds;
         }
     if(milliseconds.length()<=1)
     { milliseconds = "00";
     } 
     milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-2); 
     ((TextView)findViewById(R.id.timertxt)).setText(hours + ":" + minutes + ":" + seconds);
     }
    }

3 个答案:

答案 0 :(得分:0)

BtnStop.setOnClickListener中的大多数代码实际上都是无用的。你定义了一个名为startTimer2的Runnable,但出于什么目的?除了调用mHandler.removeCallbacks(startTimer2);之外,您永远不会使用该Runnable。这将删除之前对其进行的任何调用,但由于您从未进行任何调用,因此无法执行任何操作。

单击停止按钮时,您的方法唯一的做法是将布尔标志stopped设置为true。但是没有定期进程检查该标志。检查标志的唯一时间是按下START按钮。

作为旁注,您对REFRESH_RATE的使用令人困惑。设置更高的数字实际上会导致较低的刷新率,因为postDelayed需要一段时间。考虑重命名变量或添加一个部门。

答案 1 :(得分:0)

由于您未在boolean stopped方法中检查run,因此无法停止。把它移到里面:

public void run() {
    elapsedTime = System.currentTimeMillis() - startTime;
    updateTimer(elapsedTime);
    if(!stopped) {
        mHandler.postDelayed(this, REFRESH_RATE);
    }
}

并且还考虑根据评论中的建议声明停止为volatile

答案 2 :(得分:0)

有完整的任务启动和停止,秒表只需调用: - handler.sendEmptyMessage(MSG_STOP_TIMER);停止秒表

Handler handler = new Handler()
{
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
        case MSG_START_TIMER:
            timer.start(); //start timer

            handler.sendEmptyMessage(MSG_UPDATE_TIMER);
            break;

        case MSG_UPDATE_TIMER:
            //timerText.setText(String.format("%1$tM:%1$tS",timer.getElapsedTimeMin(),timer.getElapsedTimeSecs()));
            if ( timer.getElapsedTimeSecs() < 10)
            {
                if(timer.getElapsedTimeMin()<10){
                    timerText.setText("0" + timer.getElapsedTimeMin() + ":0" + timer.getElapsedTimeSecs());
                }else{
                    timerText.setText("" + timer.getElapsedTimeMin() + ":0" + timer.getElapsedTimeSecs());  
                }
            }
            else{
                if(timer.getElapsedTimeMin()<10){
                    timerText.setText("0" + timer.getElapsedTimeMin() + ":" + timer.getElapsedTimeSecs());
                }else{
                    timerText.setText(timer.getElapsedTimeMin()+":"+ timer.getElapsedTimeSecs());  
                }

            }
            handler.sendEmptyMessageDelayed(MSG_UPDATE_TIMER,REFRESH_RATE); //text view is updated every second,
            break;                                  //though the timer is still running
        case MSG_STOP_TIMER:
            handler.removeMessages(MSG_UPDATE_TIMER); // no more updates.
            timer.stop();//stop timer
            timerText.setText("0"+timer.getElapsedTimeMin()+":0"+ timer.getElapsedTimeSecs());
            break;

        default:
            break;
        }
    }
};