【问题标题】:Android Thread for a timer用于计时器的 Android 线程
【发布时间】:2013-07-24 16:10:55
【问题描述】:
public class MainActivity extends Activity
{
int min, sec;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    min = 5;
    sec = 0;
    final TextView timer1 = (TextView) findViewById(R.id.timer1);
    timer1.setText(min + ":" + sec);
    Thread t = new Thread() {
        public void run() {
                sec-=1;
                if (sec<0) {
                    min-=1;
                    sec=59;
                }
                timer1.setText(min + ":" + sec);
                try
                {
                    sleep(1000);
                }
                catch (InterruptedException e)
                {}
            }
    };
    t.start();
}
}

这是 Java 线程的代码,但它不起作用。你能帮帮我吗?

它是一个从 5 分钟倒计时到 0:00 的计时器。

【问题讨论】:

标签: java android


【解决方案1】:

在您的情况下,您正在使用线程。所以你不能从 ui 线程以外的线程更新 ui。所以你使用runOnUithread。我建议你使用倒数计时器或处理程序。

1.CountDownTimer

http://developer.android.com/reference/android/os/CountDownTimer.html

这是另一个示例的链接。建议您查看倒数计时器的链接。

Countdowntimer in minutes and seconds

例子:

 public class MainActivity extends Activity {

Button b; 
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tv = (TextView) findViewById(R.id.textView1);
    b= (Button) findViewById(R.id.button1);
    b.setOnClickListener(new OnClickListener()
    {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            startTimer(200000); 
        }

    });
}
private void startTimer(long time){
    CountDownTimer counter = new CountDownTimer(30000, 1000){
        public void onTick(long millisUntilDone){

           Log.d("counter_label", "Counter text should be changed");
          tv.setText("You have " + millisUntilDone + "ms");                    
        }

        public void onFinish() {
            tv.setText("DONE!");

        }
    }.start();
}
 }

2.您可以使用Handler

例子:

Handler m_handler;
Runnable m_handlerTask ; 
int timeleft=100;
m_handler = new Handler(); 
m_handlerTask = new Runnable() 
{ 
@Override
public void run() {
if(timeleft>=0)
{  
     // do stuff
     Log.i("timeleft",""+timeleft);
     timeleft--; 
}      
else
{
  m_handler.removeCallbacks(m_handlerTask); // cancel run
} 
  m_handler.postDelayed(m_handlerTask, 1000); 
 }
 };
 m_handlerTask.run();     

3.定时器

定时器在不同的线程上运行。您应该在 ui 线程上更新 ui。使用runOnUiThread

例子:

  int timeleft=100;
  Timer _t = new Timer();  
  _t.scheduleAtFixedRate( new TimerTask() {
            @Override
            public void run() {

               runOnUiThread(new Runnable() //run on ui thread
                 {
                  public void run() 
                  { 
                    Log.i("timeleft",""+timeleft);  
                    //update ui

                  }
                 });
                 if(timeleft>==0)
                 { 
                 timeleft--; 
                 } 
                 else
                 {
                 _t.cancel();
                 }
            }
        }, 1000, 1000 ); 

【讨论】:

    【解决方案2】:

    您正在尝试使用

    从背景 Thread 更新 UI Thread
    timer1.setText(
    

    这是你做不到的。您需要使用runOnUiThread()AsyncTaskCountDownTimer 或类似的东西。

    See this answerrunOnUiThread() 为例

    但是CountDownTimer 很适合这样的事情。

    此外,当在 SO 上发布问题时,诸如“它不起作用”之类的陈述。非常模糊,而且常常无济于事。如果应用程序崩溃,请指出与您的代码和 logcat 的实际结果相比的预期结果。

    【讨论】:

    • @Raghunandan 好点! +1 彻底...我懒惰并发布了链接;)
    猜你喜欢
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多