Android定时器更新文本视图(UI)

我正在使用计时器来创build秒表。 计时器通过增加一个整数值来工作。 然后我想通过不断地更新文本视图来在活动中显示这个值。

这里是我尝试更新活动的textview的服务的代码:

protected static void startTimer() { isTimerRunning = true; timer.scheduleAtFixedRate(new TimerTask() { public void run() { elapsedTime += 1; //increase every sec StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); //this is the textview } }, 0, 1000); } 

我得到了一些有关在错误的线程中更新UI的错误。

我如何调整我的代码来完成不断更新textview的任务?

谢谢。

 protected static void startTimer() { isTimerRunning = true; timer.scheduleAtFixedRate(new TimerTask() { public void run() { elapsedTime += 1; //increase every sec mHandler.obtainMessage(1).sendToTarget(); } }, 0, 1000); } public Handler mHandler = new Handler() { public void handleMessage(Message msg) { StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); //this is the textview } }; 

以上代码将工作…

注意:必须在主线程中创build处理程序,以便修改UI内容。

您应该使用Handler来每隔X秒更新一次UI。 下面是另外一个显示一个例子的问题: 延时重复一个任务?

您的方法不起作用,因为您正尝试从非UI线程更新UI。 这是不允许的。

 StopWatch.time.post(new Runnable() { StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); }); 

这个代码块是基于Handler的,但是你不需要创build你自己的Handler实例。

TimerTask实现了Runnable,这将使它成为一个线程。 您不能直接从不同的线程更新主UI线程,而无需做任何工作。 你可以做的一件事是使用asynchronous任务来创build计时器,并发布更新每秒更新用户界面。

我假设StopWatch.time是一些静态或公共引用到您的TextView。 而不是这样做,你应该实现一个BroadcastReceiver在你的计时器(从一个单独的线程运行)和你的TextView之间进行通信。

您可以使用以下实用程序:

 /** * Created by Ofek on 19/08/2015. */ public class TaskScheduler extends Handler { private ArrayMap<Runnable,Runnable> tasks = new ArrayMap<>(); public void scheduleAtFixedRate(final Runnable task,long delay,final long period) { Runnable runnable = new Runnable() { @Override public void run() { task.run(); postDelayed(this, period); } }; tasks.put(task, runnable); postDelayed(runnable, delay); } public void scheduleAtFixedRate(final Runnable task,final long period) { Runnable runnable = new Runnable() { @Override public void run() { task.run(); postDelayed(this, period); } }; tasks.put(task, runnable); runnable.run(); } public void stop(Runnable task) { Runnable removed = tasks.remove(task); if (removed!=null) removeCallbacks(removed); } } 

然后在由UI线程运行的代码中的任何地方,您都可以像这样使用它:

 TaskScheduler timer = new TaskScheduler(); timer.scheduleAtFixedRate(new Runnable() { @Override public void run() { time.setText(simpleDateFormat.format(GamePlay.instance().getLevelTime())); } },1000); 

你可以使用Handler

此代码每隔一秒增加一个计数器textView显示和更新计数器值。

 public class MainActivity extends Activity { private Handler handler = new Handler(); private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text); startTimer(); } int i = 0; Runnable runnable = new Runnable() { @Override public void run() { i++; textView.setText("counter:" + i); startTimer(); } }; public void startTimer() { handler.postDelayed(runnable, 1000); } public void cancelTimer() { handler.removeCallbacks(runnable); } @Override protected void onStop() { super.onStop(); handler.removeCallbacks(runnable); } } 
  timer.schedule(new TimerTask() { @Override public void run() { //your actions } },1*1000);//1 sec