2017-02-14 98 views
0

我正在尝试使用持续更新时间的EditText。这由一个线程处理,该线程调用一个方法来计算已用时间,并将EditText文本设置为已用时间。线程每秒钟都在睡觉。该线程在用户按下“开始”时开始,并且当用户按下“停止”时停止。当用户再次按下“开始”时,线程应重新从0开始(因为开始时间被重置)。下面是代码:停止并启动线程Android

public class MainActivity extends AppCompatActivity { 

    public Date start; 
    public Date end; 

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

     Button startButton = (Button) findViewById(R.id.startButton); 
     Button endButton = (Button) findViewById(R.id.stopButton); 
     final EditText dateEditText = (EditText) findViewById(R.id.dateEditText) ; 
     final EditText hoursEditText = (EditText) findViewById(R.id.hoursEditText); //the one I want to update 

     final DateFormat df = new SimpleDateFormat("MM/dd/yy"); 

     final Thread t = new Thread() { 

      @Override 
      public void run() { 
       try { 
        while (!isInterrupted()) { 
         Thread.sleep(1000); 
         runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 
           setTimeElapsed(hoursEditText); 
          } 
         }); 

        } 
       } catch (InterruptedException e) { 

       } 
      } 
     }; 

     startButton.setOnClickListener(new View.OnClickListener(){ 
      public void onClick(View v){ 
       start = new Date(); 
       dateEditText.setText(df.format(start)); 
       hoursEditText.setText(""); 
       t.start(); 
      } 
     }); 


     endButton.setOnClickListener(new View.OnClickListener(){ 
      public void onClick(View v){ 
       t.interrupt(); 
       if (start == null) { 
        //write error message 
       } 
       else { 
        setTimeElapsed(hoursEditText); 
        start = null; 
       } 
      } 
     }); 



    } 

    public void setTimeElapsed(EditText hoursEditText) 
    { 
     end = new Date(); 
     long diff = end.getTime() - start.getTime(); 
     String diffFormatted = String.format("%02d:%02d:%02d", 
       TimeUnit.MILLISECONDS.toHours(diff), 
       TimeUnit.MILLISECONDS.toMinutes(diff) 
         - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(diff)), 
       TimeUnit.MILLISECONDS.toSeconds(diff) 
         - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(diff))); 

     hoursEditText.setText(diffFormatted); 
    } 
} 

正如你所看到的,问题是,当我按下“停止”,然后按“启动”了,因为线程已经运行的应用程序将引发错误。如果我没有中断声明,那么应用程序崩溃,因为它认为start为空。我只想在按下停止按钮时停止线程,并在按下开始按钮时从0开始计数。

编辑:

一个我解决这个得到的方法是通过创建一个新的线程的方法,并调用该方法在我startButton听众

public void startThread(final EditText hoursEditText){ 
     t = new Thread() { 

      @Override 
      public void run() { 
       try { 
        while (!isInterrupted()) { 
         Thread.sleep(1000); 
         runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 
           setTimeElapsed(hoursEditText); 
          } 
         }); 

        } 
       } catch (InterruptedException e) { 

       } 
      } 
     }; 

     t.start(); 
    } 

但这每创建一个新线程时间有人按下开始。这不是一件好事。

+0

@jeremy你可以使用处理程序为此定时器。线程在这里矫枉过正。 – Enzokie

+0

*但是这会在每次有人按下开始时创建一个新线程。这不太好。* - 为什么不呢? –

+0

测试人员可能会连续按下500次开始按钮。除非我错了,否则会启动500个并发线程。 –

回答

0

可以使用处理器

Handler handler = new Handler(); 
final Thread thread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      setTimeElapsed(hoursEditText); 
      handler.postDelayed(this, 100); 
     } 
    }); 

//在结束按钮,点击可以删除处理程序回调

endButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       if(handler != null) 
       handler.removeCallbacksAndMessages(null); 
      } 
     }); 

完整代码

import android.os.Bundle; 
import android.os.Handler; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 

import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.TimeUnit; 

public class MainActivity extends AppCompatActivity { 

    public Date start; 
    public Date end; 
    Handler handler = new Handler(); 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     Button startButton = (Button) findViewById(R.id.startButton); 
     Button endButton = (Button) findViewById(R.id.stopButton); 
     final EditText dateEditText = (EditText) findViewById(R.id.dateEditText); 
     final EditText hoursEditText = (EditText) findViewById(R.id.hoursEditText); //the one I want to update 

     final DateFormat df = new SimpleDateFormat("MM/dd/yy"); 

     final Thread thread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       setTimeElapsed(hoursEditText); 
       handler.postDelayed(this, 100); 
      } 
     }); 

     startButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       start = new Date(); 
       dateEditText.setText(df.format(start)); 
       hoursEditText.setText(""); 
       handler.post(thread); 
      } 
     }); 


     endButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       if(handler != null) 
       handler.removeCallbacksAndMessages(null); 
      } 
     }); 


    } 

    public void setTimeElapsed(EditText hoursEditText) { 
     end = new Date(); 
     long diff = end.getTime() - start.getTime(); 
     String diffFormatted = String.format("%02d:%02d:%02d", 
       TimeUnit.MILLISECONDS.toHours(diff), 
       TimeUnit.MILLISECONDS.toMinutes(diff) 
         - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(diff)), 
       TimeUnit.MILLISECONDS.toSeconds(diff) 
         - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(diff))); 

     hoursEditText.setText(diffFormatted); 
    } 
} 
+0

谢谢。你能解释'handle.postDelayed(this,100)'行吗?我不明白它为什么是'100' –

+0

请查看* postDelayed *的详细信息https://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable,long) –